121 Commits
Author SHA1 Message Date
Ardeman 211f0154be fix: update default environment mode to local and adjust database configurations 2025-04-24 11:25:36 +08:00
Ardeman 136c4634c8 fix: enable SSL for Redis configuration in debug environment 2025-04-23 19:10:31 +08:00
Ardeman 987ac2fe4a fix: update Redis configuration to use SSL and adjust related settings 2025-04-23 19:09:24 +08:00
Ardeman 02d8a509ff fix: update Redis credentials in staging configuration 2025-04-23 18:45:49 +08:00
Ardeman e29bd7986f fix: update default environment mode to staging and add local configuration file 2025-04-23 18:18:44 +08:00
Ardeman 4bf318a9c2 fix: update PostgreSQL configuration for staging environment 2025-04-23 18:01:55 +08:00
Ardeman 52085a5be0 feat: add staging configuration file with server, database, and OSS settings 2025-04-23 17:52:58 +08:00
Ardeman 21c4c1efba fix: update MinIO endpoint and URLs to use news-cdn.legalgo.id in debug.yaml and production.yaml 2025-04-23 14:50:59 +08:00
Ardeman c17540cc20 fix: update MinIO endpoint and URLs to use crm-cdn.legalgo.id in production.yaml 2025-04-23 14:27:26 +08:00
Ardeman 714b1ff4eb fix: correct public URL formatting in GetPublicURL function 2025-04-23 13:50:41 +08:00
Ardeman abc3ce8d2b fix: update bucket name to 'uploads' in debug.yaml and production.yaml 2025-04-23 13:48:28 +08:00
Ardeman cd1097d3d0 fix: update MinIO endpoint to include the full domain in debug.yaml and production.yaml 2025-04-23 13:39:43 +08:00
Ardeman 52991059c6 fix: update bucket name to legalgonews-production in debug.yaml and production.yaml 2025-04-23 13:17:32 +08:00
Ardeman a7ef3f8ca2 fix: update SSL mode configuration in debug.yaml and NewDB function 2025-04-23 13:11:57 +08:00
Ardeman 6f1ac37915 fix: update redis host configuration in production.yaml 2025-04-23 12:57:06 +08:00
Ardeman e20c63e694 feat: add debug configuration file for server, jwt, postgresql, oss, and redis 2025-04-23 12:50:28 +08:00
Ardeman abcbc014a2 feat: add production configuration files for server, jwt, postgresql, oss, and redis 2025-04-23 12:39:50 +08:00
ericprd 98b871a5ed feat: get all staff 2025-03-25 18:01:14 +08:00
ericprd 3311b80943 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-24 22:16:17 +08:00
ericprd 16fef8706a fix: register staff return message only 2025-03-24 22:15:41 +08:00
Ardeman 4fbfa9c2c9 Merge branch 'main' of https://github.com/ardeman/project-legalgo-go
* 'main' of https://github.com/ardeman/project-legalgo-go:
  fix: search news title by query
2025-03-24 18:18:53 +08:00
ericprd a68780f09e fix: search news title by query 2025-03-24 18:11:08 +08:00
Ardeman 49dc0e4a7b refactor: update GetAll method to return NewsResponse and rename clicked to views 2025-03-24 15:24:52 +08:00
ericprd 09d9c4efb8 fix: error clicked when create new news 2025-03-24 14:02:20 +08:00
ericprd 990026cece fix: error clicked when create new news 2025-03-24 13:35:46 +08:00
ericprd 11051ae89c feat: staff get news by id 2025-03-24 13:32:05 +08:00
ericprd 24f0fe6efa fix: filter active in news 2025-03-20 13:13:28 +08:00
ericprd 8d7500610e fix: get userAgent and IP from custom header 2025-03-20 11:52:12 +08:00
ericprd 0c8133c802 fix: don't record log if staff 2025-03-20 11:19:41 +08:00
ericprd d8f6968f64 fix: improvement logs and record news access 2025-03-20 11:11:08 +08:00
ericprd 290d7f6701 fix: improvement log record ads tih ip, useragent, and uer_id 2025-03-19 22:43:31 +08:00
ericprd b0099dac1e fix: remove auth in ads log 2025-03-19 12:47:41 +08:00
ericprd d7fa8496b0 fix: add created_at field on user profile 2025-03-17 22:50:37 +08:00
ericprd efab193793 fix: add seeding spotlight category 2025-03-17 22:42:25 +08:00
ericprd 7b529ba46e fix: add clicked count on ads 2025-03-17 22:35:22 +08:00
ericprd c0dcdb77fa feat: ads log 2025-03-17 22:19:17 +08:00
ericprd ee8e8e140d fix: improvement access data 2025-03-14 13:00:12 +08:00
ericprd 11bc19360c feat: update staff data 2025-03-14 12:41:11 +08:00
ericprd 1297c71200 feat: update route ads 2025-03-13 12:00:26 +08:00
ericprd 47085ca0ae fix: add start date and end date of ads 2025-03-13 11:45:39 +08:00
ericprd ce17e9dc73 fix: update seeder 2025-03-10 12:28:56 +08:00
ericprd ce341dbc13 fix: add new fields on subscribe plan, and change status type to number in subscribe 2025-03-10 11:48:20 +08:00
ericprd 52dfb7e0f2 feat: delete ads 2025-03-10 10:50:27 +08:00
ericprd ef6b17a363 fix: image must be url in create ads 2025-03-10 10:28:23 +08:00
ericprd 1ae192ccef feat: get all ads 2025-03-09 00:55:40 +08:00
ericprd 213d370332 feat: create ads 2025-03-09 00:47:24 +08:00
ericprd 13c976dcbf fix: update user plan and rearrange structur project 2025-03-08 22:46:05 +08:00
Ardeman a47b7b7d3d feat: update Category model and request struct to use pointers for description and sequence fields 2025-03-08 00:05:04 +08:00
Ardeman c5eb6302ab feat: add description and sequence fields to Create and Update category functions 2025-03-07 23:58:53 +08:00
Ardeman 68f33d101b feat: add description and sequence fields to Category model and update request struct 2025-03-07 23:41:54 +08:00
Ardeman 479703dfd0 feat: add description field to Category model and clean up migration code 2025-03-07 23:26:54 +08:00
ericprd dc1a4dafbc fix: failed to migrate 2025-03-07 19:29:34 +08:00
ericprd fdf572cd3d feat: refactor auth package and add get users for staff 2025-03-07 17:39:26 +08:00
ericprd c48a4b944b fix: update tags and categories not updated 2025-03-07 15:16:05 +08:00
ericprd c410e651ce fix: categories filter is multiple now 2025-03-07 14:30:31 +08:00
ericprd 51b50a3132 fix: get news by query category and tags filters 2025-03-07 00:55:50 +08:00
ericprd e3a9b67e28 feat: update news 2025-03-06 23:55:46 +08:00
ericprd 2046021e01 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-06 13:30:39 +08:00
ericprd a2a6fe6374 fix: use redis config 2025-03-06 13:30:24 +08:00
Ardeman d6a680634c chore: remove deprecated jwt dependency and update to v5 2025-03-06 12:58:28 +08:00
ericprd cf410bdf05 feat: add redis config env 2025-03-06 12:56:35 +08:00
ericprd efc87ee63e Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-06 11:59:17 +08:00
ericprd c037da4879 feat: add vendor 2025-03-06 11:59:05 +08:00
0xCA7andGitHub 53fda59e3c Delete .DS_Store 2025-03-06 11:17:10 +08:00
ericprd 2525eed2ea Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-06 11:07:04 +08:00
ericprd 85247643e6 feat: get news by slug and and author detail 2025-03-06 11:06:06 +08:00
ericprd d217ec8a62 feat: delete news, tag, and category 2025-03-05 23:55:41 +08:00
ericprd 299fcf949b feat: update and delete tags and categories 2025-03-05 23:13:24 +08:00
ericprd 5c699dfa53 fix: create and get news 2025-03-05 22:15:39 +08:00
ericprd dd109c8aa0 chores: remove unused code 2025-03-05 21:27:37 +08:00
ericprd 567e0e32ca chores: refactor struct and structure project 2025-03-05 21:21:44 +08:00
altru 2b54a9343b Merge pull request 'Update Env' (#4) from feature-test into main
Reviewed-on: #4
2025-03-03 12:56:18 +00:00
aditya.siregar 30091f3362 Update Env 2025-03-03 19:55:44 +07:00
altru 43d5608a51 Merge pull request 'update docker' (#3) from feature-test into main
Reviewed-on: #3
2025-03-03 12:39:25 +00:00
aditya.siregar ed8c523b26 update docker 2025-03-03 19:39:11 +07:00
altru 883ff8b7d1 Merge pull request 'add docker file' (#2) from feature-test into main
Reviewed-on: #2
2025-03-03 12:30:23 +00:00
aditya.siregar e9b9a367a9 add docker file 2025-03-03 19:29:59 +07:00
altru 750a4dc3db Merge pull request 'Add Infra' (#1) from feature-test into main
Reviewed-on: #1
2025-03-03 12:03:19 +00:00
aditya.siregar c9f1e33c24 Add Infra 2025-03-03 18:59:25 +07:00
ericprd 13a8481f22 fix: payload update staff 2025-03-03 13:23:04 +08:00
ericprd 642566c8b2 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-03-03 10:39:38 +08:00
ericprd afe6f4e9a6 fix: change username to name and add profile pic to staff 2025-03-03 10:39:01 +08:00
Ardeman 20c9660c3a docs: add instruction to execute binary directly 2025-03-02 22:43:39 +08:00
ericprd c02d8cda69 fix: return error when there is no subscribe plan found 2025-03-02 10:07:42 +08:00
ericprd 55460653e3 fix: should be find one instead of find all 2025-03-02 09:48:40 +08:00
ericprd 915f12eaf7 feat: news router 2025-03-02 04:36:17 +08:00
ericprd f4ae93bc48 fix: condition query 2025-03-02 02:33:03 +08:00
ericprd eb1584f8c4 fix: unique entity 2025-03-01 21:27:28 +08:00
ericprd bdf6dd131e feat: category routes 2025-03-01 21:20:51 +08:00
ericprd acd80480dd feat: tag routes 2025-03-01 20:00:54 +08:00
ericprd 613379c8a5 fix: simplified gorm query 2025-03-01 19:00:12 +08:00
Ardeman c29df8a3d6 feat: add VSCode extensions recommendations 2025-02-28 22:12:35 +08:00
ericprd 2bef24fbb6 docs: fix tags 2025-02-28 22:03:47 +08:00
ericprd c23ee933c1 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-02-28 12:19:18 +08:00
ericprd 6b858b99fb fix: get profile user/staff using token rather than id 2025-02-28 12:18:47 +08:00
Ardeman 4ec50cee8a feat: add check for .env file existence before loading environment variables 2025-02-27 22:32:38 +08:00
Ardeman 84239864c1 feat: add .env file existence check before loading environment variables 2025-02-27 22:30:00 +08:00
ericprd 5fb0764630 feat: get user/staff profile 2025-02-27 18:59:58 +08:00
Ardeman 290c0edff7 docs: clean up database migration instructions in README 2025-02-27 10:48:04 +08:00
ericprd ccd92c270a Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-02-27 10:33:09 +08:00
Ardeman d2a43a88c4 docs: add migration instructions to README for database updates 2025-02-27 10:28:26 +08:00
ericprd 33ba5fbbdc Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-02-27 10:28:15 +08:00
ericprd 7b367f655e fix: docs and required field 2025-02-27 10:27:57 +08:00
Ardeman 802692f6c1 docs: update installation instructions for Go and Make across platforms 2025-02-27 10:23:24 +08:00
Ardeman 14f38b792d chore: add markdownlint configuration and update README for installation instructions 2025-02-27 10:20:55 +08:00
Ardeman da5b65b582 refactor: update module name and adjust import paths to legalgo-BE-go 2025-02-27 07:25:25 +08:00
Ardeman 0a87f85358 chore: update dependencies and bump OpenAPI version to 3.1.0 2025-02-27 06:58:12 +08:00
ericprd 0317ba04d9 Merge branch 'main' of github.com:ardeman/project-legalgo-go 2025-02-27 01:16:48 +08:00
ericprd 775a9def75 refactor: project name and set default plan for new user 2025-02-27 01:15:47 +08:00
Ardeman 27ff3996ed fix: add APP_PORT and GRACEFULL_TIMEOUT to .env.example 2025-02-26 22:54:31 +08:00
ericprd 46472d01fe fix: app port and check subscribe_plan_id 2025-02-26 22:50:13 +08:00
ericprd 0100134527 fix: refactor layout init 2025-02-26 22:28:19 +08:00
ericprd ba075b67fd fix: change path get all subscribe plan 2025-02-25 14:23:59 +08:00
ericprd aee94a5c9c fix: improvement response api and docs 2025-02-25 11:25:36 +08:00
ericprd 81c7a51256 docs: fix path 2025-02-24 20:32:08 +08:00
ericprd 3466a4b4c5 docs: fix path 2025-02-24 20:30:10 +08:00
ericprd 037acbe128 fix: path url and add docs 2025-02-24 20:27:07 +08:00
ericprd d492f3ce44 feat: get all plans and improvement 2025-02-24 20:18:09 +08:00
ericprd 3b2321d5db fix: handle duplicate input 2025-02-24 19:47:40 +08:00
ericprd bd305f0edf docs: update setup database 2025-02-24 16:53:18 +08:00
ericprd cb3d06fa02 feat: CR login, register, subscribe 2025-02-24 16:48:20 +08:00
1981 changed files with 699478 additions and 204 deletions
+12
View File
@@ -3,3 +3,15 @@ DB_USER=
DB_PASSWORD=
DB_NAME=
DB_PORT=
APP_PORT=
GRACEFULL_TIMEOUT=
SALT_SECURITY=
REDIS_HOST=
REDIS_USERNAME=
REDIS_PORT=
REDIS_PASSWORD=
REDIS_TTL=
REDIS_DB=
REDIS_TIMEOUT=
+4
View File
@@ -1,2 +1,6 @@
bin
.env
.DS_Store
/cmd/legalgo/env
__debug*
+9
View File
@@ -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>
+119
View File
@@ -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>
+8
View File
@@ -0,0 +1,8 @@
{
"default": true,
"MD013": false,
"MD026": false,
"MD033": false,
"MD040": false,
"MD041": false
}
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"arjun.swagger-viewer"
]
}
+22
View File
@@ -0,0 +1,22 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/cmd/legalgo/",
"dlvLoadConfig":{
"followPointers": true,
"maxVariableRecurse": 1,
"maxStringLen": 512, // 字符串最大长度
"maxArrayValues": 64,
"maxStructFields": -1
},
"dlvFlags": ["--check-go-version=false"],
"env": {
"TZ": ""
}
}]
}
+22
View File
@@ -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"]
+69 -6
View File
@@ -9,32 +9,41 @@ Before proceeding, make sure you have the following installed on your computer:
## Steps to Install Go 1.24.0
### For Windows:
### `go` For Windows:
1. Download the installer from [official Go website](https://golang.org/dl/).
2. Run the downloaded `.msi` file and follow the installation wizard.
3. During installation, you may be prompted to set the `GOPATH` and `GOROOT`. Choose the appropriate settings
based on your preference or keep the default values.
### For macOS:
### `go` For macOS:
1. Open Terminal.
2. Download the package using Homebrew (if not installed, visit [Homebrew website](https://brew.sh/) for
installation instructions):
```bash
brew install go@1.24
```
3. Link the installed version to your PATH:
```bash
brew link --overwrite --force go@1.24
```
### For Linux:
### `go` For Linux:
1. Open Terminal.
2. Download the appropriate tarball from [official Go website](https://golang.org/dl/).
3. Extract the downloaded archive:
```bash
tar -C /usr/local -xzf go1.24.linux-amd64.tar.gz
```
4. Add Go to your PATH by editing your shell configuration file (e.g., `.bashrc`, `.zshrc`):
```bash
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
source ~/.bashrc
@@ -43,25 +52,31 @@ installation instructions):
## Verify Installation
After installation, verify that Go 1.24.0 is installed correctly by running:
```bash
go version
```
You should see an output like `go version go1.24 darwin/amd64` (or similar, depending on your OS).
## Install Make (if not already installed)
### For Windows:
### `make` For Windows:
- Download and install [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm).
- Add the installation directory to your PATH.
### For macOS:
### `make` For macOS:
1. Open Terminal.
2. Install Make using Homebrew:
```bash
brew install make
```
### For Linux:
### `make` For Linux:
Make is usually pre-installed on most Linux distributions. If it's not installed, you can install it using your
package manager (e.g., `sudo apt-get install make` for Ubuntu).
@@ -72,13 +87,53 @@ Open Terminal and navigate to the root directory of your Go project.
## Resolve Dependencies with `go mod tidy`
Run the following command to download and resolve all dependencies specified in your `go.mod` file:
```bash
go mod tidy
```
## Setup Database
In your Go application, you'll need to set the following environment variables to connect to your database:
```bash
DB_HOST: The hostname or IP address of your database server (e.g., localhost, 127.0.0.1, or the actual DB server URL).
DB_USER: The username for your database connection.
DB_PASSWORD: The password associated with the DB_USER.
DB_NAME: The name of the database you want to connect to.
DB_PORT: The port number your database server is running on (default MySQL port is 3306, default PostgreSQL port is 5432).
```
## Create `.env` File
It's best practice to keep sensitive information like database credentials in an environment file. Create or edit the .env file in the root directory of your project and add the following lines:
```bash
DB_HOST=localhost
DB_USER=your_db_user
DB_PASSWORD=your_db_password
DB_NAME=your_db_name
DB_PORT=3306 # or 5432, depending on your DB type
APP_PORT=3000 # example
GRACEFULL_TIMEOUT=10 #example
SALT_SECURITY=your_secret_security
Make sure to replace the values with your actual database details.
```
## Migrate the Database Using `make migrate`
Before running your application, let's setup your database first.
```bash
make migrate
```
## Build the Binary Using `make build`
Run the following command to build your project. The binary will be placed in the `bin` folder.
```bash
make build
```
@@ -86,16 +141,24 @@ make build
## Run the Program Using `make run`
Finally, you can run your program using:
```bash
make run
```
This command will compile and execute your Go application.
Or you can execute the compiled binary at `bin/legalgo` by:
```bash
./bin/legalgo
```
---
**Note:** Ensure that your `Makefile` is correctly set up to handle these commands. If not, you may need to create
or adjust it accordingly.
```
Please follow the above instructions to set up Go version 1.24.0, manage dependencies using `go mod tidy`, build a
+63 -1
View File
@@ -1,5 +1,67 @@
package main
func main() {
import (
"log"
"os"
"legalgo-BE-go/config"
"legalgo-BE-go/database"
categorydomain "legalgo-BE-go/internal/domain/category"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"github.com/google/uuid"
"github.com/joho/godotenv"
)
func main() {
// Check if the .env file exists
if _, err := os.Stat(".env"); err == nil {
// Load environment variables from .env file if it exists
if err := godotenv.Load(); err != nil {
log.Println("Error loading .env file, continuing without it")
}
} else {
log.Println(".env file not found, skipping load")
}
config.InitEnv()
cfg := config.LoadConfig()
db, err := database.NewDB(cfg)
if err != nil {
log.Fatalf("failed to connect to database: %v", err)
}
// db.DropTables()
if err := db.Migrate(); err != nil {
log.Fatal("Migration failed: ", err)
}
var tempSP subscribeplandomain.SubscribePlan
var tempCtg categorydomain.Category
if err := db.Where("code = ?", "basic").First(&tempSP).Error; err != nil {
log.Print("seeding basic subscribe plan")
db.Create(&subscribeplandomain.SubscribePlan{
ID: uuid.NewString(),
Code: "basic",
Name: "Basic",
Length: 0,
Price: 0,
Status: 1,
})
}
if err := db.Where("code = ?", "spotlight").First(&tempCtg).Error; err != nil {
log.Print("seeding basic subscribe plan")
seq := 0
db.Create(&categorydomain.Category{
ID: uuid.NewString(),
Code: "spotlight",
Name: "Spotlight",
Sequence: &seq,
})
}
log.Print("migrate success")
}
+31 -13
View File
@@ -4,38 +4,55 @@ import (
"context"
"fmt"
"log"
"os"
"legalgo-BE-go/config"
"legalgo-BE-go/database"
repository "legalgo-BE-go/internal/accessor"
internalhttp "legalgo-BE-go/internal/api/http"
pkgconfig "legalgo-BE-go/internal/config"
"legalgo-BE-go/internal/services"
"github.com/ardeman/project-legalgo-go/database"
repository "github.com/ardeman/project-legalgo-go/internal/accessor"
internalhttp "github.com/ardeman/project-legalgo-go/internal/api/http"
pkgconfig "github.com/ardeman/project-legalgo-go/internal/config"
"github.com/ardeman/project-legalgo-go/internal/services"
"github.com/go-chi/chi/v5"
"github.com/joho/godotenv"
"github.com/redis/go-redis/v9"
"go.uber.org/fx"
)
func init() {
if err := godotenv.Load(); err != nil {
log.Fatal("cannot load environment file")
// Check if the .env file exists
if _, err := os.Stat(".env"); err == nil {
// Load environment variables from .env file if it exists
if err := godotenv.Load(); err != nil {
log.Println("Error loading .env file, continuing without it")
}
} else {
log.Println(".env file not found, skipping load")
}
config.InitEnv()
}
func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
func run(
lc fx.Lifecycle,
db *database.DB,
apiRouter chi.Router,
rdb *redis.Client,
) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
fmt.Println("Application has started...")
// Run migration
if err := db.Migrate(); err != nil {
log.Fatal("Migration failed: ", err)
_, err := rdb.Ping(ctx).Result()
if err != nil {
log.Fatalf("Could not connect to Redis: %v", err)
}
pkgconfig.Router(apiRouter)
return nil
},
OnStop: func(ctx context.Context) error {
fmt.Println("Shutting down...")
rdb.Close()
return nil
},
})
@@ -43,10 +60,11 @@ func run(lc fx.Lifecycle, db *database.DB, apiRouter chi.Router) {
func main() {
app := fx.New(
config.Module,
database.Module,
repository.Module,
internalhttp.Module,
services.Module,
internalhttp.Module,
fx.Invoke(run),
)
+17
View File
@@ -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)
}
+40
View File
@@ -0,0 +1,40 @@
package config
import "fmt"
var (
APP_PORT,
REDIS_DB,
REDIS_TIMEOUT,
GRACEFULL_TIMEOUT int
// DB
DB_HOST,
DB_USER,
DB_PASSWORD,
DB_NAME,
DB_PORT,
REDIS_PASSWORD,
REDIS_ADDR,
REDIS_USERNAME,
SALT_SECURITY string
)
func InitEnv() {
DB_HOST = GetOrDefault("DB_HOST", "localhost")
DB_USER = GetOrDefault("DB_USER", "")
DB_PASSWORD = GetOrDefault("DB_PASSWORD", "")
DB_NAME = GetOrDefault("DB_NAME", "")
DB_PORT = GetOrDefault("DB_PORT", "")
SALT_SECURITY = GetOrDefault("SALT_SECURITY", "legalgo")
APP_PORT = GetOrDefault("APP_PORT", 3000)
GRACEFULL_TIMEOUT = GetOrDefault("GRACEFULL_TIMEOUT", 10)
REDIS_DB = GetOrDefault("REDIS_DB", 0)
REDIS_PASSWORD = GetOrDefault("REDIS_PASSWORD", "")
REDIS_ADDR = fmt.Sprintf("%s:%s", GetOrDefault("REDIS_HOST", "localhost"), GetOrDefault("REDIS_PORT", "6379"))
REDIS_USERNAME = GetOrDefault("REDIS_USERNAME", "")
REDIS_TIMEOUT = GetOrDefault("REDIS_TIMEOUT", 60)
}
+70
View File
@@ -0,0 +1,70 @@
package config
import (
"fmt"
"os"
"sync"
"github.com/spf13/viper"
_ "gopkg.in/yaml.v3"
)
const (
YAML_PATH = "env/%s"
ENV_MODE = "ENV_MODE"
DEFAULT_ENV_MODE = "local"
)
var (
validEnvMode = map[string]struct{}{
"local": {},
"staging": {},
"production": {},
"debug": {},
}
)
type Config struct {
Server Server `mapstructure:"server"`
Database Database `mapstructure:"postgresql"`
Jwt Jwt `mapstructure:"jwt"`
OSSConfig OSSConfig `mapstructure:"oss"`
Redis Redis `mapstructure:"redis"`
}
var (
config *Config
configOnce sync.Once
)
func LoadConfig() *Config {
envMode := os.Getenv(ENV_MODE)
if _, ok := validEnvMode[envMode]; !ok {
envMode = DEFAULT_ENV_MODE // default env mode
}
cfgFilePath := fmt.Sprintf(YAML_PATH, envMode)
configOnce.Do(func() {
v := viper.New()
v.SetConfigType("yaml")
v.AddConfigPath(".")
v.SetConfigName(cfgFilePath)
if err := v.ReadInConfig(); err != nil {
panic(fmt.Errorf("failed to read config file: %s", err))
}
config = &Config{}
if err := v.Unmarshal(config); err != nil {
panic(fmt.Errorf("failed to unmarshal config: %s", err))
}
})
return config
}
func (c *Config) Auth() *AuthConfig {
return &AuthConfig{
jwtTokenSecret: c.Jwt.Token.Secret,
jwtTokenExpiresTTL: c.Jwt.Token.ExpiresTTL,
}
}
+28
View File
@@ -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
}
+34
View File
@@ -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)
}
}
+17
View File
@@ -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
}
+10
View File
@@ -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"`
}
+11
View File
@@ -0,0 +1,11 @@
package config
import (
"go.uber.org/fx"
)
var Module = fx.Module("config",
fx.Provide(
LoadConfig,
),
)
+44
View File
@@ -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
}
+14
View File
@@ -0,0 +1,14 @@
package config
type Redis struct {
Host string `mapstructure:"host"`
Port string `mapstructure:"port"`
DB int `mapstructure:"db"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
SSL bool `mapstructure:"ssl"`
Debug bool `mapstructure:"debug"`
MaxIdleConnectionsInSecond int `mapstructure:"max-idle-connections-in-second"`
MaxOpenConnectionsInSecond int `mapstructure:"max-open-connections-in-second"`
ConnectionMaxLifetimeInSecond int64 `mapstructure:"connection-max-life-time-in-second"`
}
+7
View File
@@ -0,0 +1,7 @@
package config
type Server struct {
Port string `mapstructure:"port"`
BaseUrl string `mapstructure:"common-url"`
LocalUrl string `mapstructure:"local-url"`
}
+13
View File
@@ -0,0 +1,13 @@
package database
import "time"
type Ads struct {
ID string `gorm:"primaryKey;not null" json:"id"`
ImageUrl string `gorm:"not null" json:"image_url"`
Url string `gorm:"not null" json:"url"`
StartDate *time.Time `gorm:"default:null" json:"start_date"`
EndDate *time.Time `gorm:"default:null" json:"end_date"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}
+18
View File
@@ -0,0 +1,18 @@
package database
import (
"time"
)
type Category struct {
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"not null" json:"name"`
Code string `gorm:"not null;unique" json:"code"`
Description string `gorm:"default:null" json:"description"`
Sequence int `gorm:"default:null" json:"sequence"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
News []News `gorm:"many2many:news_categories" json:"news"`
}
+14
View File
@@ -0,0 +1,14 @@
package database
import "time"
type ContentLog struct {
ID string `gorm:"primaryKey;not null" json:"id"`
ContentID string `gorm:"not null" json:"content_id"`
UserID string `gorm:"default:null" json:"user_id"`
IP string `gorm:"default:null" json:"ip"`
UserAgent string `gorm:"default:null" json:"user_agent"`
Category string `gorm:"not null" json:"category"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
}
+30 -12
View File
@@ -2,9 +2,9 @@ package database
import (
"fmt"
"os"
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
"legalgo-BE-go/config"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
@@ -13,17 +13,17 @@ type DB struct {
*gorm.DB
}
func NewDB() (*DB, error) {
var (
host = os.Getenv("DB_HOST")
user = os.Getenv("DB_USER")
password = os.Getenv("DB_PASSWORD")
dbName = os.Getenv("DB_NAME")
dbPort = os.Getenv("DB_PORT")
func NewDB(cfg *config.Config) (*DB, error) {
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%v sslmode=%s",
cfg.Database.Host,
cfg.Database.Username,
cfg.Database.Password,
cfg.Database.DB,
cfg.Database.Port,
cfg.Database.SslMode,
)
dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%v sslmode=disable", host, user, password, dbName, dbPort)
if dsn == "" {
return nil, fmt.Errorf("DATABASE_URL environment is not set")
}
@@ -37,7 +37,25 @@ func NewDB() (*DB, error) {
return &DB{db}, nil
}
func (db *DB) DropTables() error {
// Auto Migrate the User model
return db.Migrator().DropTable(
&Tag{},
&Category{},
&News{},
)
}
func (db *DB) Migrate() error {
// Auto Migrate the User model
return db.AutoMigrate(&staffmodel.Staff{})
return db.AutoMigrate(
&Staff{},
&SubscribePlan{},
&Subscribe{},
&User{},
&News{},
&Tag{},
&Category{},
&Ads{},
&ContentLog{},
)
}
+23
View File
@@ -0,0 +1,23 @@
package database
import (
"time"
)
type News struct {
ID string `gorm:"primaryKey" json:"id"`
Title string `json:"title"`
Content string `json:"content"`
Categories []Category `gorm:"many2many:news_categories" json:"categories"`
Tags []Tag `gorm:"many2many:news_tags" json:"tags"`
IsPremium bool `gorm:"default:false" json:"is_premium"`
Slug string `gorm:"default:null" json:"slug"`
FeaturedImage string `gorm:"default:null" json:"featured_image"`
AuthorID string `gorm:"not null" json:"author_id"`
LiveAt time.Time `gorm:"not null" json:"live_at"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
Author Staff `gorm:"foreignKey:AuthorID" json:"author"`
}
-11
View File
@@ -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"`
}
+16
View File
@@ -0,0 +1,16 @@
package database
import (
"time"
)
type Staff struct {
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"default:null" json:"name"`
ProfilePicture string `gorm:"default:null" json:"profile_picture"`
Email string `gorm:"unique;not null" json:"email"`
Password string `gorm:"not null" json:"password"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
}
+30
View File
@@ -0,0 +1,30 @@
package database
import (
"time"
)
type Subscribe struct {
ID string `gorm:"primaryKey" json:"id"`
SubscribePlanID string `gorm:"not null" json:"subscribe_plan_id"`
StartDate time.Time `gorm:"default:CURRENT_TIMESTAMP"`
EndDate time.Time `gorm:"default:null"`
Status int8 `gorm:"default:0"`
AutoRenew bool `gorm:"default:true"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
SubscribePlan SubscribePlan `gorm:"foreignKey:SubscribePlanID;constraint:OnDelete:CASCADE" json:"subscribe_plan"`
}
type SubscribePlan struct {
ID string `gorm:"primaryKey" json:"id"`
Code string `gorm:"not null;unique" json:"code"`
Name string `gorm:"not null" json:"name"`
Length int `gorm:"default:0" json:"length"`
Price float32 `gorm:"default:0" json:"price"`
Status int8 `gorm:"default:1" json:"status"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP"`
}
+16
View File
@@ -0,0 +1,16 @@
package database
import (
"time"
)
type Tag struct {
ID string `gorm:"primaryKey" json:"id"`
Name string `gorm:"not null" json:"name"`
Code string `gorm:"not null;unique" json:"code"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
News []News `gorm:"many2many:news_tags" json:"news"`
}
+18
View File
@@ -0,0 +1,18 @@
package database
import (
"time"
)
type User struct {
ID string `gorm:"primaryKey;not null" json:"id"`
SubscribeID string `gorm:"not null" json:"subscribe_id"`
Email string `gorm:"unique;not null" json:"email"`
Password string `gorm:"not null" json:"password"`
Phone string `gorm:"default:not null;unique" json:"phone"`
CreatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"created_at"`
UpdatedAt time.Time `gorm:"default:CURRENT_TIMESTAMP" json:"updated_at"`
DeletedAt time.Time `gorm:"default:null" json:"deleted_at"`
Subscribe Subscribe `gorm:"foreignKey:SubscribeID;constraint:OnDelete:CASCADE" json:"subscribe"`
}
+43
View File
@@ -0,0 +1,43 @@
server:
base-url: https://api.legalgo.id/core
local-url: http://localhost:3300
port: 3300
jwt:
token:
expires-ttl: 1440
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
postgresql:
host: dpg-d046h549c44c739arfv0-a.singapore-postgres.render.com
port: 5432
driver: postgres
db: legalgonews_prod
username: legalgo_admin
password: "656ogwc0JlLEVQyHnT5RrrYa7762iBQQ"
ssl-mode: require
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
oss:
access_key_id: GTK7i3SVy9llQeGH0Htv
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
endpoint: news-cdn.legalgo.id
bucket_name: uploads
log_level: Error
host_url: https://news-cdn.legalgo.id
public_url: https://news-cdn.legalgo.id
redis:
host: singapore-keyvalue.render.com
port: 6379
username: red-d046l42dbo4c73ea9iag
password: 7cZvu08JKuO9MPNxBb97tZCVNj0ZGNp2
db: 5
ssl: true
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
+43
View File
@@ -0,0 +1,43 @@
server:
base-url: https://api.legalgo.id/core
local-url: http://localhost:3300
port: 3300
jwt:
token:
expires-ttl: 1440
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
postgresql:
host: dpg-d04bi9juibrs73augcc0-a.singapore-postgres.render.com
port: 5432
driver: postgres
db: legalgonews_dev
username: legalgo_admin
password: "5h7DCBR1T8pug6AlbrHXqIDAr9o2vnky"
ssl-mode: require
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
oss:
access_key_id: GTK7i3SVy9llQeGH0Htv
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
endpoint: news-cdn.legalgo.id
bucket_name: uploads-staging
log_level: Error
host_url: https://news-cdn.legalgo.id
public_url: https://news-cdn.legalgo.id
redis:
host: singapore-keyvalue.render.com
port: 6379
username: red-d04c8k49c44c739ga8dg
password: ItPzniHv94yr8vY4HTrhCfKoibqBh61T
db: 5
ssl: true
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
+42
View File
@@ -0,0 +1,42 @@
server:
base-url: https://api.legalgo.id/core
local-url: http://localhost:3300
port: 3300
jwt:
token:
expires-ttl: 1440
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
postgresql:
host: dpg-d046h549c44c739arfv0-a
port: 5432
driver: postgres
db: legalgonews_prod
username: legalgo_admin
password: "656ogwc0JlLEVQyHnT5RrrYa7762iBQQ"
ssl-mode: disable
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
oss:
access_key_id: GTK7i3SVy9llQeGH0Htv
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
endpoint: news-cdn.legalgo.id
bucket_name: uploads
log_level: Error
host_url: https://news-cdn.legalgo.id
public_url: https://news-cdn.legalgo.id
redis:
host: red-d046l42dbo4c73ea9iag
port: 6379
password: 7cZvu08JKuO9MPNxBb97tZCVNj0ZGNp2
db: 5
ssl: false
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
+42
View File
@@ -0,0 +1,42 @@
server:
base-url: https://api.legalgo.id/core
local-url: http://localhost:3300
port: 3300
jwt:
token:
expires-ttl: 1440
secret: "5Lm25V3Qd7aut8dr4QUxm5PZUrSFs"
postgresql:
host: dpg-d04bi9juibrs73augcc0-a
port: 5432
driver: postgres
db: legalgonews_dev
username: legalgo_admin
password: "5h7DCBR1T8pug6AlbrHXqIDAr9o2vnky"
ssl-mode: disable
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
oss:
access_key_id: GTK7i3SVy9llQeGH0Htv
access_key_secret: 2psmKXZFpevA9n5ntSDRMqFBpZuSz32dvtXjYclf
endpoint: news-cdn.legalgo.id
bucket_name: uploads-staging
log_level: Error
host_url: https://news-cdn.legalgo.id
public_url: https://news-cdn.legalgo.id
redis:
host: red-d04c8k49c44c739ga8dg
port: 6379
password: ItPzniHv94yr8vY4HTrhCfKoibqBh61T
db: 5
ssl: false
max-idle-connections-in-second: 600
max-open-connections-in-second: 600
connection-max-life-time-in-second: 600
debug: false
+27 -11
View File
@@ -1,40 +1,56 @@
module github.com/ardeman/project-legalgo-go
module legalgo-BE-go
go 1.24.0
go 1.24
require (
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/joho/godotenv v1.5.1
github.com/spf13/viper v1.19.0
go.uber.org/fx v1.23.0
golang.org/x/crypto v0.34.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/postgres v1.5.7
)
require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.2 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jackc/pgx/v5 v5.4.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/joho/godotenv v1.5.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
golang.org/x/crypto v0.34.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/text v0.22.0 // indirect
gorm.io/driver/postgres v1.5.11 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
require (
github.com/aws/aws-sdk-go v1.50.0
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-chi/chi v1.5.5
github.com/go-chi/chi/v5 v5.2.1 // indirect
github.com/go-chi/chi/v5 v5.2.1
github.com/go-chi/cors v1.2.1
github.com/go-playground/validator/v10 v10.25.0
github.com/google/uuid v1.6.0
github.com/redis/go-redis/v9 v9.7.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/redis/go-redis/v9 v9.7.1
github.com/sirupsen/logrus v1.9.3
go.uber.org/dig v1.18.0 // indirect
go.uber.org/multierr v1.10.0 // indirect
go.uber.org/zap v1.26.0 // indirect
+72 -16
View File
@@ -1,18 +1,29 @@
github.com/aws/aws-sdk-go v1.50.0 h1:HBtrLeO+QyDKnc3t1+5DR1RxodOHCGr8ZcrHudpv7jI=
github.com/aws/aws-sdk-go v1.50.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/go-chi/chi v1.5.5 h1:vOB/HbEMt9QqBqErz07QehcOKHaWFtuj87tTDVz2qXE=
github.com/go-chi/chi v1.5.5/go.mod h1:C9JqLr3tIYjDOZpzn+BCuxY8z8vmca43EeMgyZt7irw=
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
@@ -21,35 +32,76 @@ github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw=
go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE=
go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg=
@@ -60,10 +112,10 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
@@ -71,15 +123,19 @@ golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
+14
View File
@@ -0,0 +1,14 @@
package adsrepository
import (
"fmt"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
func (a *accessor) Create(spec adsdomain.Ads) error {
if err := a.db.Create(&spec).Error; err != nil {
return fmt.Errorf("failed to create ads: %v", err)
}
return nil
}
+26
View File
@@ -0,0 +1,26 @@
package adsrepository
import (
"errors"
"fmt"
adsdomain "legalgo-BE-go/internal/domain/ads"
"gorm.io/gorm"
)
func (a *accessor) Delete(id string) error {
var ads adsdomain.Ads
if err := a.db.First(&ads, "id = ?", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("ads with id %s is not found", id)
}
return fmt.Errorf("failed to g ads %s : %v", id, err)
}
if err := a.db.Delete(&ads).Error; err != nil {
return fmt.Errorf("failed to delete ads %s : %v", id, err)
}
return nil
}
+20
View File
@@ -0,0 +1,20 @@
package adsrepository
import (
"fmt"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
func (a *accessor) GetAll() ([]adsdomain.AdsResponse, error) {
var ads []adsdomain.AdsResponse
if err := a.db.Table("ads").
Select("ads.*, COUNT(content_logs.content_id) as clicked").
Joins("LEFT JOIN content_logs ON content_logs.content_id = ads.id").
Group("ads.id").
Scan(&ads).Error; err != nil {
return ads, fmt.Errorf("failed to get all ads: %v", err)
}
return ads, nil
}
+23
View File
@@ -0,0 +1,23 @@
package adsrepository
import (
"legalgo-BE-go/database"
adsdomain "legalgo-BE-go/internal/domain/ads"
)
type accessor struct {
db *database.DB
}
type Ads interface {
Create(adsdomain.Ads) error
GetAll() ([]adsdomain.AdsResponse, error)
Update(adsdomain.Ads) error
Delete(string) error
}
func New(
db *database.DB,
) Ads {
return &accessor{db}
}
+31
View File
@@ -0,0 +1,31 @@
package adsrepository
import (
"fmt"
adsdomain "legalgo-BE-go/internal/domain/ads"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec adsdomain.Ads) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"image_url",
"url",
"updated_at",
"start_date",
"end_date",
}),
}).Select(
"image_url",
"url",
"updated_at",
"start_date",
"end_date",
).Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update tag: %v", err)
}
return nil
}
+24
View File
@@ -0,0 +1,24 @@
package categoryrepository
import (
"legalgo-BE-go/database"
categorydomain "legalgo-BE-go/internal/domain/category"
"github.com/google/uuid"
)
func (a *accessor) CreateModel(spec categorydomain.CategoryReq) error {
data := database.Category{
ID: uuid.NewString(),
Name: spec.Name,
Code: spec.Code,
Description: *spec.Description,
Sequence: *spec.Sequence,
}
if err := a.db.Create(&data).Error; err != nil {
return err
}
return nil
}
+24
View File
@@ -0,0 +1,24 @@
package categoryrepository
import (
"fmt"
"legalgo-BE-go/database"
)
func (a *accessor) Delete(id string) error {
var category database.Category
if err := a.db.First(&category, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to find category: %v", err)
}
if err := a.db.Model(&category).Association("News").Clear(); err != nil {
return fmt.Errorf("failed to remove categories association: %v", err)
}
if err := a.db.Delete(&category).Error; err != nil {
return fmt.Errorf("failed to delete category %s : %v", id, err)
}
return nil
}
+15
View File
@@ -0,0 +1,15 @@
package categoryrepository
import (
categorydomain "legalgo-BE-go/internal/domain/category"
)
func (a *accessor) GetAllModel() ([]categorydomain.Category, error) {
var categories []categorydomain.Category
if err := a.db.Find(&categories).Error; err != nil {
return nil, err
}
return categories, nil
}
@@ -0,0 +1,19 @@
package categoryrepository
import (
categorydomain "legalgo-BE-go/internal/domain/category"
)
func (a *accessor) GetIDByCode(codes []string) ([]string, error) {
var categories []string
if err := a.db.
Model(&categorydomain.Category{}).
Select("id").Where("code IN ?", codes).
Pluck("id", &categories).
Error; err != nil {
return nil, err
}
return categories, nil
}
+15
View File
@@ -0,0 +1,15 @@
package categoryrepository
import (
categorydomain "legalgo-BE-go/internal/domain/category"
)
func (a *accessor) GetByIDs(ids []string) ([]categorydomain.Category, error) {
var categories []categorydomain.Category
if err := a.db.Find(&categories, "id IN ?", ids).Error; err != nil {
return nil, err
}
return categories, nil
}
+25
View File
@@ -0,0 +1,25 @@
package categoryrepository
import (
"legalgo-BE-go/database"
categorydomain "legalgo-BE-go/internal/domain/category"
)
type accessor struct {
db *database.DB
}
type Category interface {
GetAllModel() ([]categorydomain.Category, error)
GetByIDs([]string) ([]categorydomain.Category, error)
GetIDByCode([]string) ([]string, error)
CreateModel(categorydomain.CategoryReq) error
Update(categorydomain.Category) error
Delete(string) error
}
func New(
db *database.DB,
) Category {
return &accessor{db}
}
+19
View File
@@ -0,0 +1,19 @@
package categoryrepository
import (
"fmt"
categorydomain "legalgo-BE-go/internal/domain/category"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec categorydomain.Category) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"name", "code", "sequence", "description", "updated_at"}),
}).Select("name", "code", "sequence", "description", "updated_at").Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update category: %v", err)
}
return nil
}
+33
View File
@@ -0,0 +1,33 @@
package logrepository
import (
"legalgo-BE-go/database"
logsdomain "legalgo-BE-go/internal/domain/logs"
"github.com/google/uuid"
)
func (a *accessor) CreateLog(spec logsdomain.LogsSpec) error {
newSpec := database.ContentLog{
ID: uuid.NewString(),
ContentID: spec.ContentID,
Category: spec.Category,
}
if spec.UserID != nil {
newSpec.UserID = *spec.UserID
}
if spec.IP != nil {
newSpec.IP = *spec.IP
}
if spec.UserAgent != nil {
newSpec.UserAgent = *spec.UserAgent
}
if err := a.db.Create(&newSpec).Error; err != nil {
return err
}
return nil
}
+21
View File
@@ -0,0 +1,21 @@
package logrepository
import (
adsdomain "legalgo-BE-go/internal/domain/ads"
)
func (a *accessor) GetAllLogAds(userID string) ([]adsdomain.Ads, error) {
var ads []adsdomain.Ads
// if err := a.db.Find(&ads, "user_id = ?", userID).Error; err != nil {
// return ads, err
// }
if err := a.db.
Joins("JOIN log_ads ON ads.id = log_ads.ads_id").
Find(&ads, "log_ads.user_id = ?", userID).Error; err != nil {
return ads, err
}
return ads, nil
}
+20
View File
@@ -0,0 +1,20 @@
package logrepository
import (
"legalgo-BE-go/database"
adsdomain "legalgo-BE-go/internal/domain/ads"
logsdomain "legalgo-BE-go/internal/domain/logs"
)
type accessor struct {
db *database.DB
}
type Log interface {
CreateLog(logsdomain.LogsSpec) error
GetAllLogAds(string) ([]adsdomain.Ads, error)
}
func New(db *database.DB) Log {
return &accessor{db}
}
+22 -1
View File
@@ -1,10 +1,31 @@
package repository
import (
staffrepository "github.com/ardeman/project-legalgo-go/internal/accessor/staff"
adsrepository "legalgo-BE-go/internal/accessor/ads"
categoryrepository "legalgo-BE-go/internal/accessor/category"
logrepository "legalgo-BE-go/internal/accessor/log"
newsrepository "legalgo-BE-go/internal/accessor/news"
"legalgo-BE-go/internal/accessor/oss"
redisaccessor "legalgo-BE-go/internal/accessor/redis"
staffrepository "legalgo-BE-go/internal/accessor/staff"
subscriberepository "legalgo-BE-go/internal/accessor/subscribe"
subscribeplanrepository "legalgo-BE-go/internal/accessor/subscribe_plan"
tagrepository "legalgo-BE-go/internal/accessor/tag"
userrepository "legalgo-BE-go/internal/accessor/user"
"go.uber.org/fx"
)
var Module = fx.Module("repository", fx.Provide(
staffrepository.New,
userrepository.New,
redisaccessor.New,
subscribeplanrepository.New,
subscriberepository.New,
tagrepository.New,
categoryrepository.New,
newsrepository.New,
oss.New,
adsrepository.New,
logrepository.New,
))
+13
View File
@@ -0,0 +1,13 @@
package newsrepository
import (
"fmt"
newsdomain "legalgo-BE-go/internal/domain/news"
)
func (a *accessor) Create(spec newsdomain.News) error {
if err := a.db.Create(&spec).Error; err != nil {
return fmt.Errorf("failed to create news: %w", err)
}
return nil
}
+28
View File
@@ -0,0 +1,28 @@
package newsrepository
import (
"fmt"
newsdomain "legalgo-BE-go/internal/domain/news"
)
func (a *accessor) Delete(id string) error {
var news newsdomain.News
if err := a.db.Preload("Categories").Preload("Tags").First(&news, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to find news: %v", err)
}
if err := a.db.Model(&news).Association("Categories").Clear(); err != nil {
return fmt.Errorf("failed to remove categories association: %v", err)
}
if err := a.db.Model(&news).Association("Tags").Clear(); err != nil {
return fmt.Errorf("failed to remove tags association: %v", err)
}
if err := a.db.Delete(&news, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to delete news %s : %v", id, err)
}
return nil
}
+52
View File
@@ -0,0 +1,52 @@
package newsrepository
import (
newsdomain "legalgo-BE-go/internal/domain/news"
timeutils "legalgo-BE-go/internal/utilities/time_utils"
)
type is_active string
const (
active is_active = "true"
notActive is_active = "false"
)
func (a *accessor) GetAll(filter newsdomain.NewsFilter) ([]newsdomain.NewsResponse, error) {
var news []newsdomain.NewsResponse
query := a.db.Table("news").
Preload("Tags").
Preload("Categories").
Preload("Author").
Joins("LEFT JOIN content_logs ON content_logs.content_id = news.id")
if len(filter.Category) > 0 {
query = query.Joins("JOIN news_categories nc ON nc.news_id = news.id").
Where("nc.category_id IN (?)", filter.Category)
}
if len(filter.Tags) > 0 {
query = query.Joins("JOIN news_tags nt ON nt.news_id = news.id").
Where("nt.tag_id IN (?)", filter.Tags)
}
if filter.Active == string(active) {
query = query.Where("news.live_at <= ?", timeutils.Now())
}
if filter.Search != "" {
query = query.Where("news.title ILIKE ?", "%"+filter.Search+"%")
}
query.
Select("news.*, COUNT(content_logs.content_id) as views").
Group("news.id").
Order("news.created_at DESC")
if err := query.
Find(&news).Error; err != nil {
return nil, err
}
return news, nil
}
+17
View File
@@ -0,0 +1,17 @@
package newsrepository
import newsdomain "legalgo-BE-go/internal/domain/news"
func (a *accessor) GetByID(id string) (*newsdomain.News, error) {
var news newsdomain.News
if err := a.db.
Preload("Tags").
Preload("Categories").
Preload("Author").
First(&news, "id = ?", id).Error; err != nil {
return nil, err
}
return &news, nil
}
+17
View File
@@ -0,0 +1,17 @@
package newsrepository
import newsdomain "legalgo-BE-go/internal/domain/news"
func (a *accessor) GetBySlug(slug string) (*newsdomain.News, error) {
var news newsdomain.News
if err := a.db.
Preload("Tags").
Preload("Categories").
Preload("Author").
First(&news, "slug = ?", slug).Error; err != nil {
return nil, err
}
return &news, nil
}
+23
View File
@@ -0,0 +1,23 @@
package newsrepository
import (
"legalgo-BE-go/database"
newsdomain "legalgo-BE-go/internal/domain/news"
)
type accessor struct {
db *database.DB
}
type News interface {
GetAll(filter newsdomain.NewsFilter) ([]newsdomain.NewsResponse, error)
GetBySlug(string) (*newsdomain.News, error)
GetByID(string) (*newsdomain.News, error)
Create(newsdomain.News) error
Update(newsdomain.News) error
Delete(string) error
}
func New(db *database.DB) News {
return &accessor{db}
}
+69
View File
@@ -0,0 +1,69 @@
package newsrepository
import (
"fmt"
categorydomain "legalgo-BE-go/internal/domain/category"
newsdomain "legalgo-BE-go/internal/domain/news"
tagdomain "legalgo-BE-go/internal/domain/tag"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec newsdomain.News) error {
tx := a.db.Begin()
if err := tx.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"title",
"content",
"featured_image",
"is_premium",
"slug",
"author_id",
"live_at",
"updated_at",
}),
}).Select(
"title",
"content",
"featured_image",
"is_premium",
"slug",
"author_id",
"live_at",
"updated_at",
).Save(&spec).Error; err != nil {
tx.Rollback()
return fmt.Errorf("failed to update news: %v", err)
}
tagsDeleted := make([]tagdomain.Tag, len(spec.Tags))
copy(tagsDeleted, spec.Tags)
if err := tx.Model(&spec).Association("Tags").Clear(); err != nil {
tx.Rollback()
return fmt.Errorf("failed to remove previous tags: %v", err)
}
if err := tx.Model(&spec).Association("Tags").Append(tagsDeleted); err != nil {
tx.Rollback()
return fmt.Errorf("failed to add tags: %v", err)
}
categoriesDeleted := make([]categorydomain.Category, len(spec.Categories))
copy(categoriesDeleted, spec.Categories)
if err := tx.Model(&spec).Association("Categories").Clear(); err != nil {
tx.Rollback()
return fmt.Errorf("failed to remove previous categories: %v", err)
}
if err := tx.Model(&spec).Association("Categories").Append(categoriesDeleted); err != nil {
tx.Rollback()
return fmt.Errorf("failed to add categories: %v", err)
}
if err := tx.Commit().Error; err != nil {
return fmt.Errorf("failed to commit transaction: %v", err)
}
return nil
}
+86
View File
@@ -0,0 +1,86 @@
package oss
import (
"bytes"
"context"
"fmt"
"legalgo-BE-go/config"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
)
type OSSConfig interface {
GetAccessKeyID() string
GetAccessKeySecret() string
GetEndpoint() string
GetBucketName() string
GetHostURL() string
GetPublicURL() string
}
const _awsRegion = "us-east-1"
const _s3ACL = "public-read"
type OssRepositoryImpl struct {
s3 *s3.S3
cfg OSSConfig
}
func New(cfg *config.Config) OSSRepository {
ossCfg := cfg.OSSConfig
sess, err := session.NewSession(&aws.Config{
S3ForcePathStyle: aws.Bool(true),
Endpoint: aws.String(ossCfg.GetEndpoint()),
Region: aws.String(_awsRegion),
Credentials: credentials.NewStaticCredentials(ossCfg.GetAccessKeyID(), ossCfg.GetAccessKeySecret(), ""),
})
if err != nil {
fmt.Println("Failed to create AWS session:", err)
return nil
}
return &OssRepositoryImpl{
s3: s3.New(sess),
cfg: ossCfg,
}
}
func (r *OssRepositoryImpl) UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error) {
reader := bytes.NewReader(fileContent)
_, err = r.s3.PutObject(&s3.PutObjectInput{
Bucket: aws.String(r.cfg.GetBucketName()),
Key: aws.String(fileName),
Body: reader,
ACL: aws.String(_s3ACL),
})
return r.GetPublicURL(fileName), err
}
func (r *OssRepositoryImpl) GetPublicURL(fileName string) string {
if fileName == "" {
return ""
}
return fmt.Sprintf("%s/%s%s", r.cfg.GetPublicURL(), r.cfg.GetBucketName(), fileName)
}
func (r *OssRepositoryImpl) DeleteObject(ctx context.Context, fileName string) error {
if fileName == "" {
return fmt.Errorf("file name is not provided")
}
_, err := r.s3.DeleteObject(&s3.DeleteObjectInput{
Key: aws.String(fileName),
})
if err != nil {
return fmt.Errorf("failed to delete object %s from bucket: %v", fileName, err)
}
return nil
}
+11
View File
@@ -0,0 +1,11 @@
package oss
import (
"context"
)
type OSSRepository interface {
UploadFile(ctx context.Context, fileName string, fileContent []byte) (fileUrl string, err error)
GetPublicURL(fileName string) string
DeleteObject(ctx context.Context, fileName string) error
}
+35
View File
@@ -0,0 +1,35 @@
package redisaccessor
import (
"crypto/tls"
"fmt"
"legalgo-BE-go/config"
"github.com/redis/go-redis/v9"
)
var redisClient *redis.Client
func Get() *redis.Client {
return redisClient
}
func New(cfg *config.Config) *redis.Client {
addr := fmt.Sprintf("%s:%s", cfg.Redis.Host, cfg.Redis.Port)
options := &redis.Options{
Addr: addr,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
}
if cfg.Redis.Username != "" {
options.Username = cfg.Redis.Username
}
if cfg.Redis.SSL {
options.TLSConfig = &tls.Config{}
}
redisClient = redis.NewClient(options)
return redisClient
}
+13
View File
@@ -0,0 +1,13 @@
package staffrepository
import (
staffdomain "legalgo-BE-go/internal/domain/staff"
)
func (ur *accessor) Create(spec staffdomain.Staff) error {
if err := ur.db.Create(&spec).Error; err != nil {
return err
}
return nil
}
+27
View File
@@ -0,0 +1,27 @@
package staffrepository
import (
"errors"
"fmt"
staffdomain "legalgo-BE-go/internal/domain/staff"
"gorm.io/gorm"
)
func (sr *accessor) GetStaffByEmail(email string) (*staffdomain.Staff, error) {
var staff staffdomain.Staff
if email == "" {
return nil, fmt.Errorf("email is required")
}
if err := sr.db.First(&staff, "email = ?", email).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("staff not found")
}
return nil, err
}
return &staff, nil
}
+26
View File
@@ -0,0 +1,26 @@
package staffrepository
import (
"errors"
"fmt"
staffdomain "legalgo-BE-go/internal/domain/staff"
"gorm.io/gorm"
)
func (sr *accessor) GetStaffByID(ID string) (*staffdomain.Staff, error) {
var staff staffdomain.Staff
if ID == "" {
return nil, fmt.Errorf("id is required")
}
if err := sr.db.First(&staff, "id = ? ", ID).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("staff not found")
}
return nil, err
}
return &staff, nil
}
+6 -18
View File
@@ -1,25 +1,13 @@
package staffrepository
import (
"errors"
import staffdomain "legalgo-BE-go/internal/domain/staff"
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
"gorm.io/gorm"
)
func (a *accessor) GetStaffs() ([]staffdomain.StaffProfile, error) {
var staffs []staffdomain.StaffProfile
func (sr *StaffRepository) GetStaff(email string) (*staffmodel.Staff, error) {
var staff staffmodel.Staff
if email == "" {
return nil, errors.New("email is empty")
if err := a.db.Table("staffs").Find(&staffs).Error; err != nil {
return staffs, err
}
if err := sr.DB.Where("email = ?", email).First(&staff).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("staff not found")
}
return nil, err
}
return &staff, nil
return staffs, nil
}
+28
View File
@@ -0,0 +1,28 @@
package staffrepository
import userdomain "legalgo-BE-go/internal/domain/user"
func (a *accessor) GetUsers() ([]userdomain.UserProfile, error) {
var usersRaw []userdomain.User
if err := a.db.
Preload("Subscribe").
Preload("Subscribe.SubscribePlan").
Find(&usersRaw).
Error; err != nil {
return nil, err
}
users := []userdomain.UserProfile{}
for _, user := range usersRaw {
users = append(users, userdomain.UserProfile{
ID: user.ID,
Email: user.Email,
Phone: user.Phone,
Subscribe: user.Subscribe,
CreatedAt: user.CreatedAt,
})
}
return users, nil
}
+14 -8
View File
@@ -1,18 +1,24 @@
package staffrepository
import (
"github.com/ardeman/project-legalgo-go/database"
staffmodel "github.com/ardeman/project-legalgo-go/database/staff"
"legalgo-BE-go/database"
staffdomain "legalgo-BE-go/internal/domain/staff"
userdomain "legalgo-BE-go/internal/domain/user"
)
type StaffRepository struct {
DB *database.DB
type accessor struct {
db *database.DB
}
type StaffInterface interface {
GetStaff(string) (*staffmodel.Staff, error)
type Staff interface {
GetStaffByEmail(string) (*staffdomain.Staff, error)
GetStaffByID(string) (*staffdomain.Staff, error)
GetUsers() ([]userdomain.UserProfile, error)
GetStaffs() ([]staffdomain.StaffProfile, error)
Create(staffdomain.Staff) error
Update(staffdomain.Staff) error
}
func New(db *database.DB) StaffInterface {
return &StaffRepository{db}
func New(db *database.DB) Staff {
return &accessor{db}
}
+18
View File
@@ -0,0 +1,18 @@
package staffrepository
import (
staffdomain "legalgo-BE-go/internal/domain/staff"
)
func (ur *accessor) Update(spec staffdomain.Staff) error {
// val, err := utils.StructToMap(spec)
// if err != nil {
// return err
// }
if err := ur.db.Model(&staffdomain.Staff{}).Where("id = ?", spec.ID).Updates(spec).Error; err != nil {
return err
}
return nil
}
+20
View File
@@ -0,0 +1,20 @@
package subscriberepository
import (
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
"github.com/google/uuid"
)
func (s *accessor) Create(subsPlanId string) (string, error) {
spec := &subscribedomain.Subscribe{
ID: uuid.NewString(),
SubscribePlanID: subsPlanId,
}
if err := s.db.Create(&spec).Error; err != nil {
return "", err
}
return spec.ID, nil
}
+23
View File
@@ -0,0 +1,23 @@
package subscriberepository
import (
"errors"
"fmt"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
"gorm.io/gorm"
)
func (s *accessor) GetByID(id string) (subscribedomain.Subscribe, error) {
var subscribe subscribedomain.Subscribe
if err := s.db.First(&subscribe, "id = ?", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return subscribe, fmt.Errorf("subscribe data not found: %v", err)
}
return subscribe, err
}
return subscribe, nil
}
+20
View File
@@ -0,0 +1,20 @@
package subscriberepository
import (
"legalgo-BE-go/database"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
)
type accessor struct {
db *database.DB
}
type Subscribe interface {
Create(string) (string, error)
GetByID(string) (subscribedomain.Subscribe, error)
Update(subscribedomain.Subscribe) error
}
func New(db *database.DB) Subscribe {
return &accessor{db}
}
+19
View File
@@ -0,0 +1,19 @@
package subscriberepository
import (
"fmt"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec subscribedomain.Subscribe) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{"status", "subscribe_plan_id", "start_date"}),
}).Create(&spec).Error; err != nil {
return fmt.Errorf("failed to update status: %v", err)
}
return nil
}
@@ -0,0 +1,13 @@
package subscribeplanrepository
import (
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
func (s *accessor) Create(spec subscribeplandomain.SubscribePlan) error {
if err := s.db.Create(&spec).Error; err != nil {
return err
}
return nil
}
@@ -0,0 +1,30 @@
package subscribeplanrepository
import (
"fmt"
"legalgo-BE-go/database"
subscribedomain "legalgo-BE-go/internal/domain/subscribe"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
func (a *accessor) Delete(id string) error {
var subsPlan database.SubscribePlan
var basicPlan subscribeplandomain.SubscribePlan
if err := a.db.First(&basicPlan, "code = ?", "basic").Error; err != nil {
return fmt.Errorf("failed to find basic plan: %v", err)
}
if err := a.db.
Model(&subscribedomain.Subscribe{}).
Where("subscribe_plan_id = ?", id).
Update("subscribe_plan_id", basicPlan.ID).Error; err != nil {
return fmt.Errorf("failed to change subscribe plan: %v", err)
}
if err := a.db.Delete(&subsPlan, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to delete subscribe plan %s : %v", id, err)
}
return nil
}
@@ -0,0 +1,15 @@
package subscribeplanrepository
import (
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
func (s *accessor) GetAll() ([]subscribeplandomain.SubscribePlan, error) {
var subscribePlans []subscribeplandomain.SubscribePlan
if err := s.db.Find(&subscribePlans).Error; err != nil {
return nil, err
}
return subscribePlans, nil
}
@@ -0,0 +1,22 @@
package subscribeplanrepository
import (
"errors"
"fmt"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"gorm.io/gorm"
)
func (s *accessor) GetByID(id string) (*subscribeplandomain.SubscribePlan, error) {
var subscribePlan *subscribeplandomain.SubscribePlan
if err := s.db.First(&subscribePlan, "id = ? ", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return subscribePlan, fmt.Errorf("subscribe plan not found")
}
return subscribePlan, err
}
return subscribePlan, nil
}
@@ -0,0 +1,22 @@
package subscribeplanrepository
import (
"legalgo-BE-go/database"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"github.com/google/uuid"
)
func (s *accessor) GetDefault() (*subscribeplandomain.SubscribePlan, error) {
var subscribePlan *subscribeplandomain.SubscribePlan
if err := s.db.First(&subscribePlan, "code = ?", "basic").Error; err != nil {
s.db.Create(&database.SubscribePlan{
ID: uuid.NewString(),
Code: "basic",
Name: "Basic",
})
}
return subscribePlan, nil
}
+25
View File
@@ -0,0 +1,25 @@
package subscribeplanrepository
import (
"legalgo-BE-go/database"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
)
type accessor struct {
db *database.DB
}
type SubscribePlan interface {
Create(subscribeplandomain.SubscribePlan) error
GetAll() ([]subscribeplandomain.SubscribePlan, error)
GetByID(string) (*subscribeplandomain.SubscribePlan, error)
GetDefault() (*subscribeplandomain.SubscribePlan, error)
Update(subscribeplandomain.SubscribePlan) error
Delete(string) error
}
func New(
db *database.DB,
) SubscribePlan {
return &accessor{db}
}
@@ -0,0 +1,33 @@
package subscribeplanrepository
import (
"fmt"
subscribeplandomain "legalgo-BE-go/internal/domain/subscribe_plan"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec subscribeplandomain.SubscribePlan) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"name",
"code",
"length",
"price",
"status",
"updated_at",
}),
}).Select(
"name",
"code",
"length",
"price",
"status",
"updated_at",
).Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update tag: %v", err)
}
return nil
}
+21
View File
@@ -0,0 +1,21 @@
package tagrepository
import (
tagdomain "legalgo-BE-go/internal/domain/tag"
"github.com/google/uuid"
)
func (acc *accessor) Create(spec tagdomain.TagReq) error {
data := &tagdomain.Tag{
ID: uuid.NewString(),
Code: spec.Code,
Name: spec.Name,
}
if err := acc.db.Create(&data).Error; err != nil {
return err
}
return nil
}
+24
View File
@@ -0,0 +1,24 @@
package tagrepository
import (
"fmt"
"legalgo-BE-go/database"
)
func (a *accessor) Delete(id string) error {
var tag database.Tag
if err := a.db.First(&tag, "id = ?", id).Error; err != nil {
return fmt.Errorf("failed to find tag: %v", err)
}
if err := a.db.Model(&tag).Association("News").Clear(); err != nil {
return fmt.Errorf("failed to remove tag association: %v", err)
}
if err := a.db.Delete(&tag).Error; err != nil {
return fmt.Errorf("failed to delete tag %s : %v", id, err)
}
return nil
}
+15
View File
@@ -0,0 +1,15 @@
package tagrepository
import (
tagdomain "legalgo-BE-go/internal/domain/tag"
)
func (acc *accessor) GetAll() ([]tagdomain.Tag, error) {
var tags []tagdomain.Tag
if err := acc.db.Find(&tags).Error; err != nil {
return nil, err
}
return tags, nil
}
+17
View File
@@ -0,0 +1,17 @@
package tagrepository
import tagdomain "legalgo-BE-go/internal/domain/tag"
func (a *accessor) GetIDsByCodes(codes []string) ([]string, error) {
var tags []string
if err := a.db.
Model(&tagdomain.Tag{}).
Select("id").Where("code IN ?", codes).
Pluck("id", &tags).
Error; err != nil {
return nil, err
}
return tags, nil
}
+13
View File
@@ -0,0 +1,13 @@
package tagrepository
import tagdomain "legalgo-BE-go/internal/domain/tag"
func (a *accessor) GetByIDs(ids []string) ([]tagdomain.Tag, error) {
var tags []tagdomain.Tag
if err := a.db.Find(&tags, "id IN ?", ids).Error; err != nil {
return nil, err
}
return tags, nil
}
+25
View File
@@ -0,0 +1,25 @@
package tagrepository
import (
"legalgo-BE-go/database"
tagdomain "legalgo-BE-go/internal/domain/tag"
)
type accessor struct {
db *database.DB
}
type TagAccessor interface {
Create(tagdomain.TagReq) error
GetAll() ([]tagdomain.Tag, error)
GetByIDs([]string) ([]tagdomain.Tag, error)
GetIDsByCodes([]string) ([]string, error)
Update(tagdomain.Tag) error
Delete(string) error
}
func New(
db *database.DB,
) TagAccessor {
return &accessor{db}
}
+23
View File
@@ -0,0 +1,23 @@
package tagrepository
import (
"fmt"
tagdomain "legalgo-BE-go/internal/domain/tag"
"gorm.io/gorm/clause"
)
func (a *accessor) Update(spec tagdomain.Tag) error {
if err := a.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "id"}},
DoUpdates: clause.AssignmentColumns([]string{
"name",
"code",
"updated_at",
}),
}).Select("name", "code", "updated_at").Save(&spec).Error; err != nil {
return fmt.Errorf("failed to update tag: %v", err)
}
return nil
}
+13
View File
@@ -0,0 +1,13 @@
package userrepository
import (
userdomain "legalgo-BE-go/internal/domain/user"
)
func (ur *accessor) CreateUser(spec userdomain.User) error {
if err := ur.db.Create(&spec).Error; err != nil {
return err
}
return nil
}
@@ -0,0 +1,26 @@
package userrepository
import (
"errors"
"fmt"
userdomain "legalgo-BE-go/internal/domain/user"
"gorm.io/gorm"
)
func (ur *accessor) GetUserByEmail(email string) (*userdomain.User, error) {
var user *userdomain.User
if email == "" {
return nil, fmt.Errorf("email is empty")
}
if err := ur.db.First(&user, "email = ?", email).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("user not found")
}
return nil, err
}
return user, nil
}
+23
View File
@@ -0,0 +1,23 @@
package userrepository
import (
"fmt"
userdomain "legalgo-BE-go/internal/domain/user"
)
func (ur *accessor) GetUserByID(id string) (*userdomain.User, error) {
var user userdomain.User
if id == "" {
return nil, fmt.Errorf("id is empty")
}
if err := ur.db.
Preload("Subscribe").
Preload("Subscribe.SubscribePlan").
First(&user, "id = ?", id).Error; err != nil {
return nil, err
}
return &user, nil
}
@@ -0,0 +1,32 @@
package userrepository
import (
"fmt"
userdomain "legalgo-BE-go/internal/domain/user"
)
func (ur *accessor) GetUserProfile(id string) (*userdomain.UserProfile, error) {
var user *userdomain.User
if id == "" {
return nil, fmt.Errorf("email is empty")
}
if err := ur.db.
Preload("Subscribe").
Preload("Subscribe.SubscribePlan").
First(&user, "id = ?", id).
Error; err != nil {
return nil, err
}
userProfile := &userdomain.UserProfile{
ID: user.ID,
Email: user.Email,
Phone: user.Phone,
Subscribe: user.Subscribe,
CreatedAt: user.CreatedAt,
}
return userProfile, nil
}
+23
View File
@@ -0,0 +1,23 @@
package userrepository
import (
"legalgo-BE-go/database"
userdomain "legalgo-BE-go/internal/domain/user"
)
type accessor struct {
db *database.DB
}
type User interface {
GetUserByEmail(string) (*userdomain.User, error)
GetUserByID(string) (*userdomain.User, error)
GetUserProfile(string) (*userdomain.UserProfile, error)
CreateUser(userdomain.User) error
}
func New(
db *database.DB,
) User {
return &accessor{db}
}
+68
View File
@@ -0,0 +1,68 @@
package adshttp
import (
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
adsdomain "legalgo-BE-go/internal/domain/ads"
adssvc "legalgo-BE-go/internal/services/ads"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-playground/validator/v10"
)
func Create(
router chi.Router,
adsSvc adssvc.Ads,
validate *validator.Validate,
) {
router.
With(authmiddleware.Authorize()).
Post("/ads/create", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var spec adsdomain.AdsReq
if err := utils.UnmarshalBody(r, &spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"failed to unmarshal body",
)
return
}
if err := validate.Struct(spec); err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.(validator.ValidationErrors).Error(),
)
return
}
if err := adsSvc.Create(spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "ads created successfully",
})
})
}
+53
View File
@@ -0,0 +1,53 @@
package adshttp
import (
"fmt"
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
adssvc "legalgo-BE-go/internal/services/ads"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
func Delete(
router chi.Router,
adsSvc adssvc.Ads,
) {
router.
With(authmiddleware.Authorize()).
Delete("/ads/{ads_id}/delete", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
adsID := chi.URLParam(r, "ads_id")
if adsID == "" {
response.RespondJsonErrorWithCode(
ctx,
w,
fmt.Errorf("ads id is not provided"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"ads id is not provided",
)
return
}
if err := adsSvc.Delete(adsID); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "ads has been deleted",
})
})
}
+32
View File
@@ -0,0 +1,32 @@
package adshttp
import (
adssvc "legalgo-BE-go/internal/services/ads"
"legalgo-BE-go/internal/utilities/response"
"net/http"
"github.com/go-chi/chi/v5"
)
func GetAll(
router chi.Router,
adsSvc adssvc.Ads,
) {
router.Get("/ads", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
subsPlan, err := adsSvc.GetAll()
if err != nil {
response.ResponseWithErrorCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, subsPlan)
})
}
+10
View File
@@ -0,0 +1,10 @@
package adshttp
import "go.uber.org/fx"
var Module = fx.Module("ads-http", fx.Invoke(
Create,
GetAll,
Update,
Delete,
))
+82
View File
@@ -0,0 +1,82 @@
package adshttp
import (
"fmt"
authmiddleware "legalgo-BE-go/internal/api/http/middleware/auth"
adsdomain "legalgo-BE-go/internal/domain/ads"
adssvc "legalgo-BE-go/internal/services/ads"
"legalgo-BE-go/internal/utilities/response"
"legalgo-BE-go/internal/utilities/utils"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-playground/validator/v10"
)
func Update(
router chi.Router,
validate *validator.Validate,
adsSvc adssvc.Ads,
) {
router.
With(authmiddleware.Authorize()).
Put("/ads/{ads_id}/update", func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
adsID := chi.URLParam(r, "ads_id")
if adsID == "" {
response.RespondJsonErrorWithCode(
ctx,
w,
fmt.Errorf("ads id is not provided"),
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"ads id is not provided",
)
return
}
var spec adsdomain.AdsReq
if err := utils.UnmarshalBody(r, &spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
"failed to unmarshal body",
)
return
}
if err := validate.Struct(spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.(validator.ValidationErrors).Error(),
)
return
}
if err := adsSvc.Update(adsID, spec); err != nil {
response.RespondJsonErrorWithCode(
ctx,
w,
err,
response.ErrBadRequest.Code,
response.ErrBadRequest.HttpCode,
err.Error(),
)
return
}
response.RespondJsonSuccess(ctx, w, struct {
Message string
}{
Message: "update ads success",
})
})
}
-9
View File
@@ -1,9 +0,0 @@
package authhttp
import "go.uber.org/fx"
var Module = fx.Module("auth-api",
fx.Invoke(
LoginStaff,
),
)

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