Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30091f3362 | ||
|
|
ed8c523b26 | ||
|
|
e9b9a367a9 | ||
|
|
c9f1e33c24 | ||
|
|
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,14 @@ 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=
|
||||
|
||||
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,6 +141,7 @@ make build
|
||||
## Run the Program Using `make run`
|
||||
|
||||
Finally, you can run your program using:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
@@ -96,6 +152,7 @@ This command will compile and execute your Go application.
|
||||
|
||||
**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
|
||||
|
||||
+47
-1
@@ -1,5 +1,51 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"legalgo-BE-go/config"
|
||||
"legalgo-BE-go/database"
|
||||
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 temp subscribeplandomain.SubscribePlan
|
||||
|
||||
if err := db.Where("code = ?", "basic").First(&temp).Error; err != nil {
|
||||
log.Print("seeding basic subscribe plan")
|
||||
db.Create(&subscribeplandomain.SubscribePlan{
|
||||
ID: uuid.NewString(),
|
||||
Code: "basic",
|
||||
Name: "Basic",
|
||||
})
|
||||
}
|
||||
|
||||
log.Print("migrate success")
|
||||
}
|
||||
|
||||
+19
-12
@@ -4,32 +4,38 @@ 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"
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// 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.Fatal("cannot load environment file")
|
||||
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) {
|
||||
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)
|
||||
}
|
||||
|
||||
pkgconfig.Router(apiRouter)
|
||||
|
||||
return nil
|
||||
@@ -43,10 +49,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,27 @@
|
||||
package config
|
||||
|
||||
var (
|
||||
APP_PORT int
|
||||
GRACEFULL_TIMEOUT int
|
||||
|
||||
// DB
|
||||
DB_HOST,
|
||||
DB_USER,
|
||||
DB_PASSWORD,
|
||||
DB_NAME,
|
||||
DB_PORT,
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
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 = "development"
|
||||
)
|
||||
|
||||
var (
|
||||
validEnvMode = map[string]struct{}{
|
||||
"local": {},
|
||||
"development": {},
|
||||
"production": {},
|
||||
}
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Server Server `mapstructure:"server"`
|
||||
Database Database `mapstructure:"postgresql"`
|
||||
Jwt Jwt `mapstructure:"jwt"`
|
||||
OSSConfig OSSConfig `mapstructure:"oss"`
|
||||
}
|
||||
|
||||
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,7 @@
|
||||
package config
|
||||
|
||||
type Server struct {
|
||||
Port string `mapstructure:"port"`
|
||||
BaseUrl string `mapstructure:"common-url"`
|
||||
LocalUrl string `mapstructure:"local-url"`
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Category struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Code string `gorm:"not null;unique" json:"code"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
|
||||
type CategoryModel struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null;unique" json:"name"`
|
||||
Code string `gorm:"not null" json:"code"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
+34
-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,16 @@ 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=disable",
|
||||
cfg.Database.Host,
|
||||
cfg.Database.Username,
|
||||
cfg.Database.Password,
|
||||
cfg.Database.DB,
|
||||
cfg.Database.Port,
|
||||
)
|
||||
|
||||
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 +36,30 @@ func NewDB() (*DB, error) {
|
||||
return &DB{db}, nil
|
||||
}
|
||||
|
||||
func (db *DB) DropTables() error {
|
||||
// Auto Migrate the User model
|
||||
return db.Migrator().DropTable(
|
||||
// &Staff{},
|
||||
// &SubscribePlan{},
|
||||
// &Subscribe{},
|
||||
// &User{},
|
||||
&Tag{},
|
||||
&Category{},
|
||||
&News{},
|
||||
)
|
||||
}
|
||||
func (db *DB) Migrate() error {
|
||||
// Auto Migrate the User model
|
||||
return db.AutoMigrate(&staffmodel.Staff{})
|
||||
return db.AutoMigrate(
|
||||
&Staff{},
|
||||
&SubscribePlan{},
|
||||
&Subscribe{},
|
||||
&User{},
|
||||
// &Tag{},
|
||||
// &Category{},
|
||||
// &News{},
|
||||
&NewsModel{},
|
||||
&TagModel{},
|
||||
&CategoryModel{},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type News struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Title string `gorm:"default:null" json:"title"`
|
||||
Tags []Tag `gorm:"many2many:news_tags" json:"tags"`
|
||||
Categories []Category `gorm:"many2many:news_categories" json:"categories"`
|
||||
Content string `gorm:"default:null" json:"content"`
|
||||
LiveAt time.Time `gorm:"not null" json:"live_at"`
|
||||
AuthorID string `gorm:"not null" json:"author_id"`
|
||||
IsPremium bool `gorm:"default:false" json:"is_premium"`
|
||||
Slug string `gorm:"default:null" json:"slug"`
|
||||
FeaturedImage string `gorm:"default:null" json:"featured_image"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
|
||||
type NewsModel struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Categories []CategoryModel `gorm:"many2many:news_categories" json:"categories"`
|
||||
Tags []TagModel `gorm:"many2many:news_tags" json:"tags"`
|
||||
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"`
|
||||
}
|
||||
@@ -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,14 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Staff struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Username string `gorm:"default:null;unique" json:"username"`
|
||||
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"`
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
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 string `gorm:"default:'inactive'"`
|
||||
AutoRenew bool `gorm:"default:true"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
|
||||
SubscribePlan SubscribePlan `gorm:"foreignKey:SubscribePlanID;constraint:OnDelete:CASCADE"`
|
||||
}
|
||||
|
||||
type SubscribePlan struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Code string `gorm:"not null;unique" json:"code"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type Tag struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Code string `gorm:"not null;unique" json:"code"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
|
||||
type TagModel struct {
|
||||
ID string `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null;unique" json:"name"`
|
||||
Code string `gorm:"not null" json:"code"`
|
||||
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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"`
|
||||
|
||||
Subscribe Subscribe `gorm:"foreignKey:SubscribeID;constraint:OnDelete:CASCADE"`
|
||||
}
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
server:
|
||||
base-url: https://api.legalgo.id/core
|
||||
local-url: http://localhost:3300
|
||||
port: 3300
|
||||
|
||||
jwt:
|
||||
token:
|
||||
expires-ttl: 1440
|
||||
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
|
||||
|
||||
postgresql:
|
||||
host: 62.72.45.250
|
||||
port: 20826
|
||||
driver: postgres
|
||||
db: legalgonews-dev
|
||||
username: legalgo_admin
|
||||
password: 'K4K!2Kg7c@KW6H&4A2aBy2dFCRY3Sh'
|
||||
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: cf9a475e18bc7626cbdbf09709d82a64
|
||||
access_key_secret: 91f3321294d3e23035427a0ecb893ada
|
||||
endpoint: sin1.contabostorage.com
|
||||
bucket_name: legalgonews-dev
|
||||
log_level: Error
|
||||
host_url: https://sin1.contabostorage.com
|
||||
public_url: https://sin1.contabostorage.com/fda98c2228f246f29a7e466b86b3b9e7
|
||||
@@ -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.4.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.2.0 // 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,30 @@
|
||||
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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 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 +33,89 @@ 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-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.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.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8=
|
||||
github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
|
||||
github.com/jackc/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
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.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
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.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.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=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
|
||||
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
|
||||
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
|
||||
@@ -60,26 +126,67 @@ 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.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
|
||||
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
|
||||
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
|
||||
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
|
||||
gorm.io/driver/postgres v1.4.7 h1:J06jXZCNq7Pdf7LIPn8tZn9LsWjd81BRSKveKNr0ZfA=
|
||||
gorm.io/driver/postgres v1.4.7/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4=
|
||||
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
|
||||
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package categoryrepository
|
||||
|
||||
import (
|
||||
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (a *accessor) Create(spec categorydomain.CategoryReq) error {
|
||||
data := categorydomain.Category{
|
||||
ID: uuid.NewString(),
|
||||
Name: spec.Name,
|
||||
Code: spec.Code,
|
||||
}
|
||||
|
||||
if err := a.DB.Create(&data).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package categoryrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (a *accessor) CreateModel(spec categorydomain.CategoryReq) error {
|
||||
data := database.CategoryModel{
|
||||
ID: uuid.NewString(),
|
||||
Name: spec.Name,
|
||||
Code: spec.Code,
|
||||
}
|
||||
|
||||
if err := a.DB.Create(&data).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package categoryrepository
|
||||
|
||||
import categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
|
||||
func (a *accessor) GetAll() ([]categorydomain.Category, error) {
|
||||
var categories []categorydomain.Category
|
||||
|
||||
if err := a.DB.Find(&categories).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package categoryrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
)
|
||||
|
||||
func (a *accessor) GetAllModel() ([]database.CategoryModel, error) {
|
||||
var categories []database.CategoryModel
|
||||
|
||||
if err := a.DB.Find(&categories).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
@@ -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,15 @@
|
||||
package categoryrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
)
|
||||
|
||||
func (a *accessor) GetBulks(ids []string) ([]database.CategoryModel, error) {
|
||||
var categories []database.CategoryModel
|
||||
|
||||
if err := a.DB.Find(&categories, "id IN ?", ids).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return categories, nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package categoryrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
)
|
||||
|
||||
type accessor struct {
|
||||
DB *database.DB
|
||||
}
|
||||
|
||||
type Category interface {
|
||||
Create(categorydomain.CategoryReq) error
|
||||
CreateModel(categorydomain.CategoryReq) error
|
||||
|
||||
GetAll() ([]categorydomain.Category, error)
|
||||
GetAllModel() ([]database.CategoryModel, error)
|
||||
|
||||
GetByIDs([]string) ([]categorydomain.Category, error)
|
||||
GetBulks([]string) ([]database.CategoryModel, error)
|
||||
}
|
||||
|
||||
func New(
|
||||
db *database.DB,
|
||||
) Category {
|
||||
return &accessor{db}
|
||||
}
|
||||
@@ -1,10 +1,27 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
staffrepository "github.com/ardeman/project-legalgo-go/internal/accessor/staff"
|
||||
categoryrepository "legalgo-BE-go/internal/accessor/category"
|
||||
newsrepository "legalgo-BE-go/internal/accessor/news"
|
||||
"legalgo-BE-go/internal/accessor/oss"
|
||||
redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
||||
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
|
||||
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribeplan"
|
||||
tagrepository "legalgo-BE-go/internal/accessor/tag"
|
||||
userrepository "legalgo-BE-go/internal/accessor/user_repository"
|
||||
|
||||
"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,
|
||||
))
|
||||
|
||||
@@ -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,13 @@
|
||||
package newsrepository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"legalgo-BE-go/database"
|
||||
)
|
||||
|
||||
func (a *accessor) CreateModel(spec database.NewsModel) error {
|
||||
if err := a.db.Create(&spec).Error; err != nil {
|
||||
return fmt.Errorf("failed to create news: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package newsrepository
|
||||
|
||||
import newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
|
||||
func (a *accessor) GetAll() ([]newsdomain.News, error) {
|
||||
var news []newsdomain.News
|
||||
|
||||
if err := a.db.Preload("Tags").Preload("Categories").Find(&news).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return news, nil
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package newsrepository
|
||||
|
||||
import "legalgo-BE-go/database"
|
||||
|
||||
func (a *accessor) GetAllModel() ([]database.NewsModel, error) {
|
||||
var news []database.NewsModel
|
||||
|
||||
if err := a.db.Preload("Tags").Preload("Categories").Find(&news).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return news, nil
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package newsrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
)
|
||||
|
||||
type accessor struct {
|
||||
db *database.DB
|
||||
}
|
||||
|
||||
type News interface {
|
||||
GetAll() ([]newsdomain.News, error)
|
||||
GetAllModel() ([]database.NewsModel, error)
|
||||
Create(*newsdomain.News) error
|
||||
CreateModel(database.NewsModel) error
|
||||
}
|
||||
|
||||
func New(db *database.DB) News {
|
||||
return &accessor{db}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
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)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package oss
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type OSSRepository interface {
|
||||
UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error)
|
||||
GetPublicURL(fileName string) string
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package redisaccessor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
var redisClient *redis.Client
|
||||
|
||||
func Get() *redis.Client {
|
||||
return redisClient
|
||||
}
|
||||
|
||||
func New() *redis.Client {
|
||||
var (
|
||||
username = os.Getenv("REDIS_USERNAME")
|
||||
addr = fmt.Sprintf("%s:%s", os.Getenv("REDIS_HOST"), os.Getenv("REDIS_PORT"))
|
||||
password = os.Getenv("REDIS_PASSWORD")
|
||||
db = 2 // TODO: change later
|
||||
)
|
||||
|
||||
redisClient = redis.NewClient(&redis.Options{
|
||||
Username: username,
|
||||
Addr: addr,
|
||||
Password: password,
|
||||
DB: db,
|
||||
})
|
||||
|
||||
return redisClient
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package staffrepository
|
||||
|
||||
import authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
|
||||
func (ur *StaffRepository) Create(spec *authdomain.Staff) (*authdomain.Staff, error) {
|
||||
if err := ur.DB.Create(&spec).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return spec, nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (sr *StaffRepository) GetStaffByEmail(email string) (*authdomain.Staff, error) {
|
||||
var staff authdomain.Staff
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is required")
|
||||
}
|
||||
|
||||
if err := sr.DB.First(&staff, "email = ?", email).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staff, nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (sr *StaffRepository) GetStaffByID(ID string) (*authdomain.Staff, error) {
|
||||
var staff authdomain.Staff
|
||||
|
||||
if ID == "" {
|
||||
return nil, errors.New("id is required")
|
||||
}
|
||||
|
||||
if err := sr.DB.First(&staff, "id = ? ", ID).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("staff not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staff, nil
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (sr *StaffRepository) GetStaff(email string) (*staffmodel.Staff, error) {
|
||||
var staff staffmodel.Staff
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,18 +1,21 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
"github.com/ardeman/project-legalgo-go/database"
|
||||
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
|
||||
"legalgo-BE-go/database"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
)
|
||||
|
||||
type StaffRepository struct {
|
||||
DB *database.DB
|
||||
}
|
||||
|
||||
type StaffInterface interface {
|
||||
GetStaff(string) (*staffmodel.Staff, error)
|
||||
type StaffIntf interface {
|
||||
GetStaffByEmail(string) (*authdomain.Staff, error)
|
||||
GetStaffByID(string) (*authdomain.Staff, error)
|
||||
Create(*authdomain.Staff) (*authdomain.Staff, error)
|
||||
Update(authdomain.Staff) error
|
||||
}
|
||||
|
||||
func New(db *database.DB) StaffInterface {
|
||||
func New(db *database.DB) StaffIntf {
|
||||
return &StaffRepository{db}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package staffrepository
|
||||
|
||||
import (
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
)
|
||||
|
||||
func (ur *StaffRepository) Update(spec authdomain.Staff) error {
|
||||
val, err := utils.StructToMap(spec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ur.DB.Model(&authdomain.Staff{}).Where("id = ?", spec.ID).Updates(val).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package subscriberepository
|
||||
|
||||
import (
|
||||
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (s *SubsAccs) 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,15 @@
|
||||
package subscriberepository
|
||||
|
||||
import "legalgo-BE-go/database"
|
||||
|
||||
type SubsAccs struct {
|
||||
DB *database.DB
|
||||
}
|
||||
|
||||
type SubsIntf interface {
|
||||
Create(string) (string, error)
|
||||
}
|
||||
|
||||
func New(db *database.DB) SubsIntf {
|
||||
return &SubsAccs{db}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package subscribeplanrepository
|
||||
|
||||
import (
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (s *SubsPlan) Create(spec subscribeplandomain.SubscribePlanReq) error {
|
||||
data := &subscribeplandomain.SubscribePlan{
|
||||
ID: uuid.NewString(),
|
||||
Code: spec.Code,
|
||||
Name: spec.Name,
|
||||
}
|
||||
|
||||
if err := s.DB.Create(&data).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package subscribeplanrepository
|
||||
|
||||
import (
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
)
|
||||
|
||||
func (s *SubsPlan) 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,21 @@
|
||||
package subscribeplanrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (s *SubsPlan) 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, errors.New("subscribe plan not found")
|
||||
}
|
||||
return subscribePlan, err
|
||||
}
|
||||
|
||||
return subscribePlan, nil
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package subscribeplanrepository
|
||||
|
||||
import (
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (s *SubsPlan) GetDefault() (subscribeplandomain.SubscribePlan, error) {
|
||||
var subscribePlan subscribeplandomain.SubscribePlan
|
||||
|
||||
if err := s.DB.First(&subscribePlan, "code = ?", "basic").Error; err != nil {
|
||||
s.DB.Create(&subscribeplandomain.SubscribePlan{
|
||||
ID: uuid.NewString(),
|
||||
Code: "basic",
|
||||
Name: "Basic",
|
||||
})
|
||||
}
|
||||
|
||||
return subscribePlan, nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package subscribeplanrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
)
|
||||
|
||||
type SubsPlan struct {
|
||||
DB *database.DB
|
||||
}
|
||||
|
||||
type SubsPlanIntf interface {
|
||||
Create(subscribeplandomain.SubscribePlanReq) error
|
||||
GetAll() ([]subscribeplandomain.SubscribePlan, error)
|
||||
GetByID(string) (subscribeplandomain.SubscribePlan, error)
|
||||
GetDefault() (subscribeplandomain.SubscribePlan, error)
|
||||
}
|
||||
|
||||
func New(
|
||||
db *database.DB,
|
||||
) SubsPlanIntf {
|
||||
return &SubsPlan{db}
|
||||
}
|
||||
@@ -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,22 @@
|
||||
package tagrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func (acc *accessor) CreateModel(spec tagdomain.TagReq) error {
|
||||
data := &database.TagModel{
|
||||
ID: uuid.NewString(),
|
||||
Code: spec.Code,
|
||||
Name: spec.Name,
|
||||
}
|
||||
|
||||
if err := acc.DB.Create(&data).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -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,13 @@
|
||||
package tagrepository
|
||||
|
||||
import "legalgo-BE-go/database"
|
||||
|
||||
func (acc *accessor) GetAllModel() ([]database.TagModel, error) {
|
||||
var tags []database.TagModel
|
||||
|
||||
if err := acc.DB.Find(&tags).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
@@ -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,13 @@
|
||||
package tagrepository
|
||||
|
||||
import "legalgo-BE-go/database"
|
||||
|
||||
func (a *accessor) GetBulks(ids []string) ([]database.TagModel, error) {
|
||||
var tags []database.TagModel
|
||||
|
||||
if err := a.DB.Find(&tags, "id IN ?", ids).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package tagrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||
)
|
||||
|
||||
type accessor struct {
|
||||
DB *database.DB
|
||||
}
|
||||
|
||||
type TagAccessor interface {
|
||||
Create(tagdomain.TagReq) error
|
||||
CreateModel(tagdomain.TagReq) error
|
||||
GetAll() ([]tagdomain.Tag, error)
|
||||
GetAllModel() ([]database.TagModel, error)
|
||||
GetByIDs([]string) ([]tagdomain.Tag, error)
|
||||
GetBulks(ids []string) ([]database.TagModel, error)
|
||||
}
|
||||
|
||||
func New(
|
||||
db *database.DB,
|
||||
) TagAccessor {
|
||||
return &accessor{db}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
)
|
||||
|
||||
func (ur *UserRepository) CreateUser(spec *authdomain.User) (*authdomain.User, error) {
|
||||
if err := ur.DB.Create(&spec).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return spec, nil
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (ur *UserRepository) GetUserByEmail(email string) (*authdomain.User, error) {
|
||||
var user authdomain.User
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
}
|
||||
|
||||
if err := ur.DB.First(&user, "email = ?", email).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &user, nil
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (ur *UserRepository) GetUserByID(email string) (*authdomain.UserProfile, error) {
|
||||
var users []authdomain.UserProfile
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
}
|
||||
|
||||
if err := ur.DB.Table("users u").
|
||||
Select("u.email, u.id, s.status as subscribe_status, sp.code as subscribe_plan_code, sp.name as subscribe_plan_name").
|
||||
Joins("join subscribes s on s.id = u.subscribe_id").
|
||||
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
|
||||
Scan(&users).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &users[0], nil
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func (ur *UserRepository) GetUserProfile(email string) (*authdomain.UserProfile, error) {
|
||||
var users []authdomain.UserProfile
|
||||
|
||||
if email == "" {
|
||||
return nil, errors.New("email is empty")
|
||||
}
|
||||
|
||||
if err := ur.DB.Table("users u").
|
||||
Where("email = ?", email).
|
||||
Select("u.email, u.id, s.status as subscribe_status, sp.code as subscribe_plan_code, sp.name as subscribe_plan_name").
|
||||
Joins("join subscribes s on s.id = u.subscribe_id").
|
||||
Joins("join subscribe_plans sp on s.subscribe_plan_id = sp.id").
|
||||
Scan(&users).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &users[0], nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package userrepository
|
||||
|
||||
import (
|
||||
"legalgo-BE-go/database"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
)
|
||||
|
||||
type UserRepository struct {
|
||||
DB *database.DB
|
||||
}
|
||||
|
||||
type UserIntf interface {
|
||||
GetUserByEmail(string) (*authdomain.User, error)
|
||||
GetUserByID(string) (*authdomain.UserProfile, error)
|
||||
GetUserProfile(string) (*authdomain.UserProfile, error)
|
||||
CreateUser(*authdomain.User) (*authdomain.User, error)
|
||||
}
|
||||
|
||||
func New(
|
||||
db *database.DB,
|
||||
) UserIntf {
|
||||
return &UserRepository{db}
|
||||
}
|
||||
@@ -3,25 +3,26 @@ package authhttp
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
domain "github.com/ardeman/project-legalgo-go/internal/domain/auth"
|
||||
serviceauth "github.com/ardeman/project-legalgo-go/internal/services/auth"
|
||||
"github.com/ardeman/project-legalgo-go/internal/utilities/response"
|
||||
"github.com/ardeman/project-legalgo-go/internal/utilities/utils"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func LoginStaff(
|
||||
router chi.Router,
|
||||
authSvc serviceauth.LoginStaffIntf,
|
||||
authSvc authsvc.AuthIntf,
|
||||
validate *validator.Validate,
|
||||
) {
|
||||
router.Post("/staff/login", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var request domain.StaffLoginReq
|
||||
var spec authdomain.LoginReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &request); err != nil {
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
@@ -33,7 +34,7 @@ func LoginStaff(
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(request); err != nil {
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
@@ -45,7 +46,7 @@ func LoginStaff(
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authSvc.LoginAsStaff(request.Email)
|
||||
token, err := authSvc.LoginAsStaff(spec)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
@@ -58,7 +59,62 @@ func LoginStaff(
|
||||
return
|
||||
}
|
||||
|
||||
responsePayload := &domain.StaffLoginResponse{
|
||||
responsePayload := &authdomain.AuthResponse{
|
||||
Token: token,
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, responsePayload)
|
||||
})
|
||||
}
|
||||
|
||||
func LoginUser(
|
||||
router chi.Router,
|
||||
authSvc authsvc.AuthIntf,
|
||||
validate *validator.Validate,
|
||||
) {
|
||||
router.Post("/user/login", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var spec authdomain.LoginReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal request",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authSvc.LoginAsUser(spec)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
responsePayload := &authdomain.AuthResponse{
|
||||
Token: token,
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,11 @@ import "go.uber.org/fx"
|
||||
var Module = fx.Module("auth-api",
|
||||
fx.Invoke(
|
||||
LoginStaff,
|
||||
LoginUser,
|
||||
RegisterUser,
|
||||
RegisterStaff,
|
||||
UpdateStaff,
|
||||
GetStaffProfile,
|
||||
GetUserProfile,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package authhttp
|
||||
|
||||
import (
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetStaffProfile(
|
||||
router chi.Router,
|
||||
authSvc authsvc.AuthIntf,
|
||||
) {
|
||||
router.Get("/staff/profile", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
destructedToken, err := utils.GetTokenDetail(r)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
staffProfile, err := authSvc.GetStaffProfile(destructedToken.Email)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, staffProfile)
|
||||
})
|
||||
}
|
||||
|
||||
func GetUserProfile(
|
||||
router chi.Router,
|
||||
authSvc authsvc.AuthIntf,
|
||||
) {
|
||||
router.Get("/user/profile", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
destructedToken, err := utils.GetTokenDetail(r)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
userProfile, err := authSvc.GetUserProfile(destructedToken.Email)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, userProfile)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package authhttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func RegisterUser(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
authSvc authsvc.AuthIntf,
|
||||
) {
|
||||
router.Post("/user/register", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var spec authdomain.RegisterUserReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal request",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authSvc.RegisterUser(spec)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
responsePayload := &authdomain.AuthResponse{
|
||||
Token: token,
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, responsePayload)
|
||||
})
|
||||
}
|
||||
|
||||
func RegisterStaff(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
authSvc authsvc.AuthIntf,
|
||||
) {
|
||||
router.Post("/staff/register", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var spec authdomain.RegisterStaffReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal request",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := authSvc.RegisterStaff(spec)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
responsePayload := &authdomain.AuthResponse{
|
||||
Token: token,
|
||||
}
|
||||
response.RespondJsonSuccess(ctx, w, responsePayload)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package authhttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
authdomain "legalgo-BE-go/internal/domain/auth"
|
||||
authsvc "legalgo-BE-go/internal/services/auth"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func UpdateStaff(
|
||||
router chi.Router,
|
||||
authSvc authsvc.AuthIntf,
|
||||
) {
|
||||
router.Patch("/staff/{id}/update", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
id := chi.URLParam(r, "id")
|
||||
if id == "" {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
errors.New("provided id is empty"),
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"required params is not provided",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
var spec authdomain.RegisterStaffReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal request",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
staff := authdomain.Staff{
|
||||
ID: id,
|
||||
Email: spec.Email,
|
||||
Password: spec.Password,
|
||||
Username: spec.Username,
|
||||
}
|
||||
|
||||
if err := authSvc.UpdateStaff(staff); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
responsePayload := struct{
|
||||
Message string
|
||||
} {
|
||||
Message: "update staff success",
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, responsePayload)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package categoryhttp
|
||||
|
||||
import (
|
||||
categorydomain "legalgo-BE-go/internal/domain/category"
|
||||
categorysvc "legalgo-BE-go/internal/services/category"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func Create(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
categorySvc categorysvc.Category,
|
||||
) {
|
||||
router.Post("/category/create", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var spec categorydomain.CategoryReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := categorySvc.Create(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrCreateEntity.Code,
|
||||
response.ErrCreateEntity.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "category created successfully",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package categoryhttp
|
||||
|
||||
import (
|
||||
categorysvc "legalgo-BE-go/internal/services/category"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetAll(
|
||||
router chi.Router,
|
||||
categorySvc categorysvc.Category,
|
||||
) {
|
||||
router.Get("/category", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
subsPlan, err := categorySvc.GetAllModel()
|
||||
// subsPlan, err := categorySvc.GetAll()
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, subsPlan)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package categoryhttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("categories", fx.Invoke(
|
||||
Create,
|
||||
GetAll,
|
||||
))
|
||||
@@ -0,0 +1,5 @@
|
||||
package contenthttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("content-api", fx.Invoke())
|
||||
@@ -0,0 +1,138 @@
|
||||
package authmiddleware
|
||||
|
||||
// import (
|
||||
// "context"
|
||||
// "fmt"
|
||||
// "net/http"
|
||||
// "strings"
|
||||
|
||||
// redisaccessor "legalgo-BE-go/internal/accessor/redis"
|
||||
// contextkeyenum "legalgo-BE-go/internal/enums/context_key"
|
||||
// jwtclaimenum "legalgo-BE-go/internal/enums/jwt"
|
||||
// resourceenum "legalgo-BE-go/internal/enums/resource"
|
||||
// "legalgo-BE-go/internal/services/auth"
|
||||
// "github.com/golang-jwt/jwt/v5"
|
||||
// )
|
||||
|
||||
// const SessionHeader = "Authorization"
|
||||
|
||||
// func Authorization() func(next http.Handler) http.Handler {
|
||||
// return func(next http.Handler) http.Handler {
|
||||
// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// ctx := r.Context()
|
||||
|
||||
// tokenString, err := GetToken(r)
|
||||
// if err != nil {
|
||||
// RespondWithError(w, r, err, "Invalid auth header")
|
||||
// return
|
||||
// }
|
||||
|
||||
// token, err := ValidateToken(ctx, tokenString)
|
||||
// if err != nil {
|
||||
// RespondWithError(w, r, err, err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
// if isAuthorized, ctx := VerifyClaims(ctx, token, nil); !isAuthorized {
|
||||
// RespondWithError(w, r, errorcode.ErrCodeUnauthorized, errorcode.ErrCodeUnauthorized.Message)
|
||||
// return
|
||||
// } else {
|
||||
// next.ServeHTTP(w, r.WithContext(ctx))
|
||||
// return
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
// func GetToken(r *http.Request) (string, error) {
|
||||
// tokenString := GetTokenFromHeader(r)
|
||||
// if tokenString == "" {
|
||||
// tokenString = getTokenFromQuery(r)
|
||||
// }
|
||||
|
||||
// if tokenString == "" {
|
||||
// return "", fmt.Errorf("token not found")
|
||||
// }
|
||||
|
||||
// return tokenString, nil
|
||||
// }
|
||||
|
||||
// func GetTokenFromHeader(r *http.Request) string {
|
||||
// session := r.Header.Get(SessionHeader)
|
||||
// arr := strings.Split(session, " ")
|
||||
|
||||
// if len(arr) != 2 || strings.ToUpper(arr[0]) != "BEARER" {
|
||||
// return ""
|
||||
// }
|
||||
|
||||
// return arr[1]
|
||||
// }
|
||||
|
||||
// func getTokenFromQuery(r *http.Request) string {
|
||||
// token := r.URL.Query().Get("token")
|
||||
// return token
|
||||
// }
|
||||
|
||||
// func VerifyClaims(ctx context.Context, token *jwt.Token,
|
||||
// requiredResources []resourceenum.Resource) (bool, context.Context) {
|
||||
// if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
|
||||
// rawResources := []interface{}{}
|
||||
// if claimValue, exist := claims[string(jwtclaimenum.RESOURCES)]; exist {
|
||||
// rawResources = claimValue.([]interface{})
|
||||
// }
|
||||
|
||||
// resources := []resourceenum.Resource{}
|
||||
// resourceMap := map[string]bool{}
|
||||
|
||||
// for _, v := range rawResources {
|
||||
// value := v.(string)
|
||||
// resources = append(resources, resourceenum.Resource(value))
|
||||
// resourceMap[value] = true
|
||||
// }
|
||||
|
||||
// ctx = context.WithValue(ctx, contextkeyenum.Authorization, UserAuthorization{
|
||||
// Type: claims[string(jwtclaimenum.TYPE)].(string),
|
||||
// UserId: claims[string(jwtclaimenum.AUDIENCE)].(string),
|
||||
// Username: claims[string(jwtclaimenum.USERNAME)].(string),
|
||||
// Resources: resources,
|
||||
// })
|
||||
|
||||
// isResourceFulfilled := false
|
||||
|
||||
// for _, v := range requiredResources {
|
||||
// if _, ok := resourceMap[string(v)]; ok {
|
||||
// isResourceFulfilled = true
|
||||
// ctx = context.WithValue(ctx, contextkeyenum.Resource, v)
|
||||
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
|
||||
// if isResourceFulfilled || len(requiredResources) == 0 {
|
||||
// return true, ctx
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false, nil
|
||||
// }
|
||||
|
||||
// func ValidateToken(ctx context.Context, tokenString string) (*jwt.Token, error) {
|
||||
// redisClient := redisaccessor.Get()
|
||||
// redisToken, err := redisClient.Exists(ctx, fmt.Sprintf("%s:%s", auth.BLACKLISTED_TOKEN_KEY, tokenString)).Result()
|
||||
|
||||
// if err != nil || redisToken > 0 {
|
||||
// return nil, fmt.Errorf("session already expired")
|
||||
// }
|
||||
|
||||
// token, err := jwt.Parse(tokenString, authsvc.VerifyToken(conf.JWTAccessToken))
|
||||
// if err != nil {
|
||||
// if ve, ok := err.(*jwt.ValidationError); ok {
|
||||
// if ve.Errors&jwt.ValidationErrorExpired != 0 {
|
||||
// err = errorcode.ErrCodeExpiredToken
|
||||
// }
|
||||
// }
|
||||
// return nil, err
|
||||
// }
|
||||
|
||||
// return token, nil
|
||||
// }
|
||||
@@ -0,0 +1,93 @@
|
||||
package newshttp
|
||||
|
||||
import (
|
||||
staffrepository "legalgo-BE-go/internal/accessor/staff"
|
||||
newsdomain "legalgo-BE-go/internal/domain/news"
|
||||
newssvc "legalgo-BE-go/internal/services/news"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func Create(
|
||||
validate *validator.Validate,
|
||||
newsSvc newssvc.News,
|
||||
staffRepo staffrepository.StaffIntf,
|
||||
router chi.Router,
|
||||
) {
|
||||
router.Post("/news/create", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var spec newsdomain.NewsReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
destructedToken, err := utils.GetTokenDetail(r)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
staffProfile, err := staffRepo.GetStaffByEmail(destructedToken.Email)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := newsSvc.CreateModel(spec, staffProfile.ID); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "news created successfully.",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package newshttp
|
||||
|
||||
import (
|
||||
newssvc "legalgo-BE-go/internal/services/news"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetAll(
|
||||
router chi.Router,
|
||||
newsSvc newssvc.News,
|
||||
) {
|
||||
router.Get("/news", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
news, err := newsSvc.GetAllModel()
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, news)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package newshttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("news", fx.Invoke(
|
||||
GetAll,
|
||||
Create,
|
||||
))
|
||||
@@ -0,0 +1,11 @@
|
||||
package osshttp
|
||||
|
||||
import (
|
||||
"go.uber.org/fx"
|
||||
)
|
||||
|
||||
var Module = fx.Module("upload",
|
||||
fx.Invoke(
|
||||
RegisterUploadFile,
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,92 @@
|
||||
package osshttp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
oss2 "legalgo-BE-go/internal/domain/oss"
|
||||
"legalgo-BE-go/internal/services/oss"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
const _oneMB = 1 << 20
|
||||
const _maxUploadSize = 2 * _oneMB
|
||||
const _folderName = "/file"
|
||||
|
||||
func RegisterUploadFile(ossService oss.OSSService, router chi.Router) {
|
||||
router.Post("/file", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
// Limit the size of the request body to prevent very large uploads.
|
||||
r.Body = http.MaxBytesReader(w, r.Body, int64(_maxUploadSize))
|
||||
if err := r.ParseMultipartForm(int64(_maxUploadSize)); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"Failed to parse multipart form",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Retrieve the file from the form.
|
||||
file, header, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"Failed to retrieve file",
|
||||
)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Check if file size exceeds the maximum limit.
|
||||
if header.Size > int64(_maxUploadSize) {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
fmt.Errorf("file too big"),
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
fmt.Sprintf("The file is too big. The maximum size is %d MB", _maxUploadSize/_oneMB),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Prepare the request for the OSS service.
|
||||
uploadReq := &oss2.UploadFileRequest{
|
||||
FileHeader: header,
|
||||
FolderName: _folderName,
|
||||
}
|
||||
|
||||
// Call the OSS service to handle the file upload.
|
||||
result, err := ossService.UploadFile(ctx, uploadReq)
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Return a successful JSON response.
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}{
|
||||
Message: "File uploaded successfully.",
|
||||
Data: result,
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
package internalhttp
|
||||
|
||||
import (
|
||||
authhttp "github.com/ardeman/project-legalgo-go/internal/api/http/auth"
|
||||
authhttp "legalgo-BE-go/internal/api/http/auth"
|
||||
categoryhttp "legalgo-BE-go/internal/api/http/category"
|
||||
newshttp "legalgo-BE-go/internal/api/http/news"
|
||||
osshttp "legalgo-BE-go/internal/api/http/oss"
|
||||
subscribeplanhttp "legalgo-BE-go/internal/api/http/subscribe_plan"
|
||||
taghttp "legalgo-BE-go/internal/api/http/tag"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/go-playground/validator/v10"
|
||||
@@ -16,6 +22,11 @@ var Module = fx.Module("router",
|
||||
validator.New,
|
||||
),
|
||||
authhttp.Module,
|
||||
subscribeplanhttp.Module,
|
||||
taghttp.Module,
|
||||
categoryhttp.Module,
|
||||
newshttp.Module,
|
||||
osshttp.Module,
|
||||
)
|
||||
|
||||
func initRouter() chi.Router {
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package subscribeplanhttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
|
||||
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func CreateSubscribePlan(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
subsSvc subscribeplansvc.SubsPlanIntf,
|
||||
) {
|
||||
router.Post("/subscribe-plan/create", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var spec subscribeplandomain.SubscribePlanReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal request",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := subsSvc.CreatePlan(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrCreateEntity.Code,
|
||||
response.ErrCreateEntity.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "subscription plan created successfully.",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package subscribeplanhttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
subscribeplansvc "legalgo-BE-go/internal/services/subscribe_plan"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetAllPlan(
|
||||
router chi.Router,
|
||||
subsPlanSvc subscribeplansvc.SubsPlanIntf,
|
||||
) {
|
||||
router.Get("/subscribe-plan", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
subsPlan, err := subsPlanSvc.GetAllPlan()
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
response.ErrBadRequest.Message,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, subsPlan)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package subscribeplanhttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("subscribe-plan",
|
||||
fx.Invoke(
|
||||
CreateSubscribePlan,
|
||||
GetAllPlan,
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,67 @@
|
||||
package taghttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
tagdomain "legalgo-BE-go/internal/domain/tag"
|
||||
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"legalgo-BE-go/internal/utilities/utils"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
func Create(
|
||||
router chi.Router,
|
||||
validate *validator.Validate,
|
||||
tagSvc tagsvc.TagIntf,
|
||||
) {
|
||||
router.Post("/tag/create", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var spec tagdomain.TagReq
|
||||
|
||||
if err := utils.UnmarshalBody(r, &spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
"failed to unmarshal request",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := validate.Struct(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.(validator.ValidationErrors).Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if err := tagSvc.Create(spec); err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrCreateEntity.Code,
|
||||
response.ErrCreateEntity.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, struct {
|
||||
Message string
|
||||
}{
|
||||
Message: "tag created successfully.",
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package taghttp
|
||||
|
||||
import (
|
||||
tagsvc "legalgo-BE-go/internal/services/tag"
|
||||
"legalgo-BE-go/internal/utilities/response"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func GetAll(
|
||||
router chi.Router,
|
||||
tagSvc tagsvc.TagIntf,
|
||||
) {
|
||||
router.Get("/tag", func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
tags, err := tagSvc.GetAllModel()
|
||||
// tags, err := tagSvc.GetAll()
|
||||
if err != nil {
|
||||
response.ResponseWithErrorCode(
|
||||
ctx,
|
||||
w,
|
||||
err,
|
||||
response.ErrBadRequest.Code,
|
||||
response.ErrBadRequest.HttpCode,
|
||||
err.Error(),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
response.RespondJsonSuccess(ctx, w, tags)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package taghttp
|
||||
|
||||
import "go.uber.org/fx"
|
||||
|
||||
var Module = fx.Module("tag", fx.Invoke(
|
||||
Create,
|
||||
GetAll,
|
||||
))
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"legalgo-BE-go/config"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sync/errgroup"
|
||||
@@ -16,26 +18,26 @@ import (
|
||||
func Router(apiRouter chi.Router) {
|
||||
mainRouter := chi.NewRouter()
|
||||
|
||||
mainRouter.Mount("/", apiRouter)
|
||||
mainRouter.Mount("/api", apiRouter)
|
||||
mainCtx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
svr := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", APP_PORT),
|
||||
Addr: fmt.Sprintf(":%d", config.APP_PORT),
|
||||
Handler: mainRouter,
|
||||
}
|
||||
|
||||
group, groupCtx := errgroup.WithContext(mainCtx)
|
||||
|
||||
group.Go(func() error {
|
||||
logrus.Infof("Listening to port %d", APP_PORT)
|
||||
logrus.Infof("Listening to port %d", config.APP_PORT)
|
||||
return svr.ListenAndServe()
|
||||
})
|
||||
|
||||
group.Go(func() error {
|
||||
<-groupCtx.Done()
|
||||
|
||||
ctxTimeout, cancel := context.WithTimeout(mainCtx, GRACEFULL_TIMEOUT*time.Second)
|
||||
ctxTimeout, cancel := context.WithTimeout(mainCtx, time.Duration(config.GRACEFULL_TIMEOUT)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
svr.Shutdown(ctxTimeout)
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
package pkgconfig
|
||||
|
||||
const APP_PORT = 3000
|
||||
const GRACEFULL_TIMEOUT = 20
|
||||
@@ -0,0 +1,31 @@
|
||||
package authdomain
|
||||
|
||||
type LoginReq struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
type AuthResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type LoginRepoResponse struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type StaffProfile struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type UserProfile struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
SubscribePlanCode string `json:"subscribe_plan_code"`
|
||||
SubscribePlanName string `json:"subscribe_plan_name"`
|
||||
SubscribeStatus string `json:"subscribe_status"`
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package authdomain
|
||||
|
||||
type RegisterUserReq struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Phone string `json:"phone" validate:"required"`
|
||||
SubscribePlanID string `json:"subscribe_plan_id"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Phone string `json:"phone"`
|
||||
SubscribeID string `json:"subscribe_id"`
|
||||
}
|
||||
|
||||
type RegisterStaffReq struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
Username string `json:"username" validate:"required"`
|
||||
}
|
||||
|
||||
type UpdateStaffReq struct {
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type Staff struct {
|
||||
ID string `json:"id"`
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package domain
|
||||
|
||||
type StaffLoginReq struct {
|
||||
Email string `json:"email" validate:"required"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
type StaffLoginResponse struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package authdomain
|
||||
|
||||
type AuthToken struct {
|
||||
Email string
|
||||
SessionID string
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user