Merge pull request 'dev' (#6) from dev into main

Reviewed-on: winter-access/backend_nam#6
This commit is contained in:
areeqakbr 2025-02-18 01:47:11 +00:00
commit afbfc80e55
30 changed files with 1224 additions and 46 deletions

14
.dockerignore Normal file
View File

@ -0,0 +1,14 @@
# Ignore compiled binaries and temp files
*.exe
*.out
*.o
*.a
# Ignore Go build artifacts
bin/
pkg/
vendor/
# Ignore git files
.git
.gitignore

76
.gitea/workflows/dev.yaml Normal file
View File

@ -0,0 +1,76 @@
name: Deploy Golang App to Kubernetes Cluster
on:
push:
branches:
- dev
jobs:
build:
name: Build and push image
runs-on: ubuntu-latest
container:
image: ghcr.io/catthehacker/ubuntu:act-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Get short SHA
id: get-short-sha
run: |
id=$(echo ${{ github.sha }} | cut -c 1-7)
echo "id=$id" >> $GITHUB_ENV
- name: Login to registry
uses: docker/login-action@v3
with:
registry: git.winteraccess.id
username: ${{ vars.REGISTRY_USER }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Build and push to registry
uses: docker/build-push-action@v5
with:
context: .
file: deploy/docker/Dockerfile
push: true
tags: |
git.winteraccess.id/winter-access/backend_nam:dev-${{ env.id }}
git.winteraccess.id/winter-access/backend_nam:dev
git.winteraccess.id/winter-access/backend_nam:latest
deploy:
name: Deploy to kubernetes cluster
runs-on: ubuntu-latest
needs:
- build
container:
image: ghcr.io/catthehacker/ubuntu:act-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Get short SHA
id: get-short-sha
run: |
id=$(echo ${{ github.sha }} | cut -c 1-7)
echo "::set-output name=id::$id"
- name: Create Kubeconfig
run: |
mkdir $HOME/.kube
echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config
- name: Setup Kubectl
uses: azure/setup-kubectl@v4
- name: Set the Kubernetes context
uses: azure/k8s-set-context@v2
with:
method: service-account
k8s-url: ${{ vars.KUBE_URL }}
k8s-secret: ${{ secrets.KUBE_SECRET }}
- name: Deploy to the Kubernetes cluster
uses: azure/k8s-deploy@v5
with:
action: deploy
namespace: walanja-dev
manifests: |
deploy/kubernetes/dev.yaml
images: |
git.winteraccess.id/winter-access/backend_nam:${{ steps.get-version.outputs.version }}-dev-${{ steps.get-short-sha.outputs.id }}

3
.gitignore vendored
View File

@ -21,8 +21,7 @@ out/
# Vendor directory # Vendor directory
vendor/ vendor/
# Go modules
go.sum
# IDE and editor files # IDE and editor files
.vscode/ .vscode/

View File

@ -2,11 +2,13 @@ package controller
import ( import (
"net/http" "net/http"
"users_management/m/middleware"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/usecase" "users_management/m/usecase"
"users_management/m/utils/common" "users_management/m/utils/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
type BackboneController struct { type BackboneController struct {
@ -16,8 +18,13 @@ type BackboneController struct {
func (bc *BackboneController) Route() { func (bc *BackboneController) Route() {
rg := bc.rg.Group("/backbone") rg := bc.rg.Group("/backbone")
rg.GET("", bc.GetBackbone()) rg.Use(middleware.AuthMiddleware())
rg.POST("", bc.CreateBackbone()) {
rg.GET("", bc.GetBackbone())
rg.POST("", bc.CreateBackbone())
rg.GET("/:uuid", bc.GetBackboneByID())
rg.PUT("/:uuid", bc.UpdateBackbone())
}
} }
func NewBackboneController(bu usecase.BackboneUseCase, rg *gin.RouterGroup) *BackboneController { func NewBackboneController(bu usecase.BackboneUseCase, rg *gin.RouterGroup) *BackboneController {
@ -60,3 +67,50 @@ func (bc *BackboneController) CreateBackbone() gin.HandlerFunc {
common.SingleResponses(c, "Backbone has been created", nil) common.SingleResponses(c, "Backbone has been created", nil)
} }
} }
func (bc *BackboneController) GetBackboneByID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
backbone, err := bc.bu.GetByID(uuid)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Success", backbone)
}
}
func (bc *BackboneController) UpdateBackbone() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
var backboneDTO req.UpdateBackboneDTO
err = c.ShouldBindJSON(&backboneDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
err = bc.bu.UpdateBackbone(uuid, backboneDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Backbone has been updated", nil)
}
}

View File

@ -2,11 +2,13 @@ package controller
import ( import (
"net/http" "net/http"
"users_management/m/middleware"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/usecase" "users_management/m/usecase"
"users_management/m/utils/common" "users_management/m/utils/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
type DevicePortController struct { type DevicePortController struct {
@ -16,8 +18,13 @@ type DevicePortController struct {
func (dc *DevicePortController) Route() { func (dc *DevicePortController) Route() {
rg := dc.rg.Group("/device-port") rg := dc.rg.Group("/device-port")
rg.GET("", dc.GetDevicePort()) rg.Use(middleware.AuthMiddleware())
rg.POST("", dc.CreateDevicePort()) {
rg.GET("", dc.GetDevicePort())
rg.POST("", dc.CreateDevicePort())
rg.GET("/:uuid", dc.GetDevicePortByID())
rg.PUT("/:uuid", dc.UpdateDevicePort())
}
} }
func NewDevicePortController(du usecase.DevicePortUseCase, rg *gin.RouterGroup) *DevicePortController { func NewDevicePortController(du usecase.DevicePortUseCase, rg *gin.RouterGroup) *DevicePortController {
@ -60,3 +67,50 @@ func (dc *DevicePortController) CreateDevicePort() gin.HandlerFunc {
common.SingleResponses(c, "Device Port has been created", nil) common.SingleResponses(c, "Device Port has been created", nil)
} }
} }
func (dc *DevicePortController) GetDevicePortByID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
devicePort, err := dc.du.GetByID(uuid)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Success", devicePort)
}
}
func (dc *DevicePortController) UpdateDevicePort() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
var devicePortDTO req.UpdateDevicePort
err = c.ShouldBindJSON(&devicePortDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
err = dc.du.UpdateDevicePort(uuid, devicePortDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Device Port has been updated", nil)
}
}

View File

@ -2,11 +2,13 @@ package controller
import ( import (
"net/http" "net/http"
"users_management/m/middleware"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/usecase" "users_management/m/usecase"
"users_management/m/utils/common" "users_management/m/utils/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
type DeviceController struct { type DeviceController struct {
@ -16,8 +18,13 @@ type DeviceController struct {
func (dc *DeviceController) Route() { func (dc *DeviceController) Route() {
rg := dc.rg.Group("/devices") rg := dc.rg.Group("/devices")
rg.POST("", dc.CreateDevice()) rg.Use(middleware.AuthMiddleware())
rg.GET("", dc.GetAllDevices()) {
rg.POST("", dc.CreateDevice())
rg.GET("", dc.GetAllDevices())
rg.GET("/:uuid", dc.GetDeviceByID())
rg.PUT("/:uuid", dc.UpdateDevice())
}
} }
func NewDeviceController(du usecase.DeviceUseCase, rg *gin.RouterGroup) *DeviceController { func NewDeviceController(du usecase.DeviceUseCase, rg *gin.RouterGroup) *DeviceController {
@ -60,3 +67,49 @@ func (dc *DeviceController) GetAllDevices() gin.HandlerFunc {
common.SingleResponses(c, "Success", devices) common.SingleResponses(c, "Success", devices)
} }
} }
func (dc *DeviceController) GetDeviceByID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("id")
uuid, err := uuid.Parse(id)
if err != nil{
common.ErrorResponses(c, http.StatusBadGateway, err.Error())
return
}
device, err := dc.du.GetByID(uuid)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Success", device)
}
}
func (dc *DeviceController) UpdateDevice() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("id")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
var deviceDTO req.UpdateDeviceDTO
err = c.ShouldBindJSON(&deviceDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
err = dc.du.UpdateDevice(uuid, deviceDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Device has been updated", nil)
}
}

View File

@ -2,11 +2,13 @@ package controller
import ( import (
"net/http" "net/http"
"users_management/m/middleware"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/usecase" "users_management/m/usecase"
"users_management/m/utils/common" "users_management/m/utils/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
type FishboneController struct { type FishboneController struct {
@ -16,8 +18,13 @@ type FishboneController struct {
func (fc *FishboneController) Route() { func (fc *FishboneController) Route() {
rg := fc.rg.Group("/fishbone") rg := fc.rg.Group("/fishbone")
rg.GET("", fc.GetFishbone()) rg.Use(middleware.AuthMiddleware())
rg.POST("", fc.CreateFishbone()) {
rg.GET("", fc.GetFishbone())
rg.POST("", fc.CreateFishbone())
rg.GET("/:uuid", fc.GetFishboneByID())
rg.PUT("/:uuid", fc.UpdateFishbone())
}
} }
func NewFishboneController(fu usecase.FishboneUseCase, rg *gin.RouterGroup) *FishboneController { func NewFishboneController(fu usecase.FishboneUseCase, rg *gin.RouterGroup) *FishboneController {
@ -60,3 +67,50 @@ func (fc *FishboneController) CreateFishbone() gin.HandlerFunc {
common.SingleResponses(c, "Fishbone has been created", nil) common.SingleResponses(c, "Fishbone has been created", nil)
} }
} }
func (fc *FishboneController) GetFishboneByID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil{
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
fishbone, err := fc.fu.GetByID(uuid)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Success", fishbone)
}
}
func (fc *FishboneController) UpdateFishbone() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
var fishboneDTO req.UpdateFishboneDTO
err = c.ShouldBindJSON(&fishboneDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
err = fc.fu.UpdateFishbone(uuid, fishboneDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Fishbone has been updated", nil)
}
}

View File

@ -2,11 +2,13 @@ package controller
import ( import (
"net/http" "net/http"
"users_management/m/middleware"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/usecase" "users_management/m/usecase"
"users_management/m/utils/common" "users_management/m/utils/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid"
) )
type TowerController struct { type TowerController struct {
@ -16,8 +18,13 @@ type TowerController struct {
func (tc *TowerController) Route() { func (tc *TowerController) Route() {
rg := tc.rg.Group("/tower") rg := tc.rg.Group("/tower")
rg.GET("", tc.GetTower()) rg.Use(middleware.AuthMiddleware())
rg.POST("", tc.CreateTower()) {
rg.GET("", tc.GetTower())
rg.POST("", tc.CreateTower())
rg.GET("/:uuid", tc.GetTowerByID())
rg.PUT("/:uuid", tc.UpdateTower())
}
} }
func NewTowerController(tu usecase.TowerUseCase, rg *gin.RouterGroup) *TowerController { func NewTowerController(tu usecase.TowerUseCase, rg *gin.RouterGroup) *TowerController {
@ -60,3 +67,48 @@ func (tc *TowerController) CreateTower() gin.HandlerFunc {
common.SingleResponses(c, "Tower has been created", nil) common.SingleResponses(c, "Tower has been created", nil)
} }
} }
func (tc *TowerController) GetTowerByID() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
tower, err := tc.tu.GetByID(uuid)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Success", tower)
}
}
func (tc *TowerController) UpdateTower() gin.HandlerFunc {
return func(c *gin.Context) {
id := c.Param("uuid")
uuid, err := uuid.Parse(id)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
}
var towerUpdateDTO req.UpdateTowerDTO
err = c.ShouldBindJSON(&towerUpdateDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
err = tc.tu.UpdateTower(uuid, towerUpdateDTO)
if err != nil {
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
return
}
common.SingleResponses(c, "Tower has been updated", nil)
}
}

View File

@ -5,6 +5,7 @@ import (
"users_management/m/config" "users_management/m/config"
"users_management/m/delivery/controller" "users_management/m/delivery/controller"
"users_management/m/manager" "users_management/m/manager"
"users_management/m/middleware"
"users_management/m/utils/common" "users_management/m/utils/common"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -43,11 +44,14 @@ func NewServer() *Server {
func (s *Server) setupController() { func (s *Server) setupController() {
rg := s.engine.Group("/api/v1") rg := s.engine.Group("/api/v1")
controller.NewUsersController(s.ucManager.NewUserUsecase(), s.ucManager.NewAuthUsecase(),rg).Route() controller.NewUsersController(s.ucManager.NewUserUsecase(), s.ucManager.NewAuthUsecase(),rg).Route()
controller.NewDeviceController(s.ucManager.NewDeviceUsecase(), rg).Route() rg.Use(middleware.AuthMiddleware())
controller.NewBackboneController(s.ucManager.NewBackboneUsecase(), rg).Route() {
controller.NewFishboneController(s.ucManager.NewFishboneUsecase(), rg).Route() controller.NewDeviceController(s.ucManager.NewDeviceUsecase(), rg).Route()
controller.NewTowerController(s.ucManager.NewTowerUsecase(), rg).Route() controller.NewBackboneController(s.ucManager.NewBackboneUsecase(), rg).Route()
controller.NewDevicePortController(s.ucManager.NewDevicePortUsecase(), rg).Route() controller.NewFishboneController(s.ucManager.NewFishboneUsecase(), rg).Route()
controller.NewTowerController(s.ucManager.NewTowerUsecase(), rg).Route()
controller.NewDevicePortController(s.ucManager.NewDevicePortUsecase(), rg).Route()
}
} }
func (s *Server) Run() { func (s *Server) Run() {

18
deploy/docker/Dockerfile Normal file
View File

@ -0,0 +1,18 @@
# Use the official Golang image
FROM golang:1.23.1
# Set the working directory inside the container
WORKDIR /app
# Copy go.mod and go.sum files and download dependencies
COPY go.mod go.sum ./
RUN go mod download
# Copy the rest of the application source code
COPY . .
# Expose the application's port (change if needed)
EXPOSE 5678
# Command to run the application
CMD ["go", "run", "main.go"]

334
deploy/kubernetes/dev.yaml Normal file
View File

@ -0,0 +1,334 @@
apiVersion: v1
kind: Secret
metadata:
name: nam-backend-dev-secret
namespace: nam-backend-dev
labels:
app.kubernetes.io/name: nam-backend-dev
app.kubernetes.io/instance: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
type: Opaque
data:
DB_PASSWORD: MTIzUVdFYXNkenhjLQ==
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nam-backend-dev-config
namespace: nam-backend-dev
labels:
app.kubernetes.io/name: nam-backend-dev
app.kubernetes.io/instance: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
data:
".env": |
DB_HOST=172.16.224.55
DB_PORT=5433
DB_NAME=db_asset_network
DB_USER=cifo_asset_network
DB_DRIVER=postgres
API_PORT=5678
API_LOGIN_URL=https://demo.api-hrm.winteraccess.id/api/v2/auth/login
API_ME_URL=https://demo.api-hrm.winteraccess.id/api/v2/auth/me
API_LOGOUT_URL=https://demo.api-hrm.winteraccess.id/api/v2/auth/logout
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
volume.alpha.kubernetes.io/storage-class: generic
volume.beta.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner
volume.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner
labels:
app.kubernetes.io/name: nam-backend-dev
app.kubernetes.io/instance: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
name: nam-backend-dev-storage
namespace: nam-backend-dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nfs
volumeMode: Filesystem
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
volume.alpha.kubernetes.io/storage-class: generic
volume.beta.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner
volume.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner
labels:
app.kubernetes.io/name: nam-backend-dev
app.kubernetes.io/instance: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
name: nam-backend-dev-public
namespace: nam-backend-dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nfs
volumeMode: Filesystem
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
annotations:
volume.alpha.kubernetes.io/storage-class: generic
volume.beta.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner
volume.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner
labels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
name: nam-backend-dev-public
namespace: nam-backend-dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: nfs
volumeMode: Filesystem
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nam-backend-dev
namespace: nam-backend-dev
labels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
spec:
progressDeadlineSeconds: 600
replicas: 3
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
topologyKey: "kubernetes.io/hostname"
containers:
- name: web
image: https://git.winteraccess.id/winter-access/backend_nam:dev
imagePullPolicy: Always
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: nam-backend-dev-secret
key: DB_PASSWORD
resources:
limits:
cpu: "250m"
memory: 1024M
requests:
cpu: "100m"
memory: 512M
ports:
- containerPort: 80
name: http
protocol: TCP
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_ADMIN", "SYS_TIME"]
readOnlyRootFilesystem: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /app
name: app
initContainers:
- name: init
image: https://git.winteraccess.id/winter-access/backend_nam:dev
imagePullPolicy: Always
command: ["/scripts/initialize"]
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: nam-backend-dev-secret
key: DB_PASSWORD
resources:
limits:
cpu: "250m"
memory: 1024M
requests:
cpu: "100m"
memory: 512M
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_ADMIN", "SYS_TIME"]
readOnlyRootFilesystem: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /app
name: app
imagePullSecrets:
- name: winter-registry
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext:
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
runAsNonRoot: true
terminationGracePeriodSeconds: 30
volumes:
- name: cache
emptyDir: {}
- name: run
emptyDir: {}
- name: logs
emptyDir: {}
- name: tmp
emptyDir: {}
- name: psysh
emptyDir: {}
- name: config
configMap:
name: nam-backend-dev-config
- name: public
persistentVolumeClaim:
claimName: nam-backend-dev-public
- name: storage
persistentVolumeClaim:
claimName: nam-backend-dev-storage
---
apiVersion: v1
kind: Service
metadata:
name: nam-backend-dev
namespace: nam-backend-dev
annotations:
traefik.ingress.kubernetes.io/service.sticky.cookie: "true"
traefik.ingress.kubernetes.io/service.sticky.cookie.name: "backend_nam_dev"
traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true"
traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none"
labels:
app.kubernetes.io/name: nam-backend-dev
app.kubernetes.io/instance: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
spec:
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 80
protocol: TCP
targetPort: 5678
selector:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
sessionAffinity: None
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.ingress.kubernetes.io/router.middlewares: default-https-redirect@kubernetescrd
labels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
name: nam-backend-dev-http
namespace: nam-backend-dev
spec:
ingressClassName: traefik
rules:
- host: dev-nam.winteraccess.id
http:
paths:
- backend:
service:
name: nam-backend-dev
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: websecure
labels:
app.kubernetes.io/instance: nam-backend-dev
app.kubernetes.io/name: nam-backend-dev
io.portainer.kubernetes.application.name: nam-backend-dev
io.portainer.kubernetes.application.owner: admin
name: nam-backend-dev-https
namespace: nam-backend-dev
spec:
ingressClassName: traefik
rules:
- host: dev-nam.winteraccess.id
http:
paths:
- backend:
service:
name: nam-backend-dev
port:
number: 80
path: /
pathType: Prefix
tls:
- hosts:
- dev-nam.winteraccess.id
secretName: nam-backend-dev-tls

1
go.mod
View File

@ -15,6 +15,7 @@ require (
github.com/bytedance/sonic v1.12.8 // indirect github.com/bytedance/sonic v1.12.8 // indirect
github.com/bytedance/sonic/loader v0.2.3 // indirect github.com/bytedance/sonic/loader v0.2.3 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect github.com/cloudwego/base64x v0.1.5 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.0.0 // indirect github.com/gin-contrib/sse v1.0.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect

118
go.sum Normal file
View File

@ -0,0 +1,118 @@
github.com/bytedance/sonic v1.12.8 h1:4xYRVRlXIgvSZ4e8iVTlMF5szgpXd4AfvuWgA8I8lgs=
github.com/bytedance/sonic v1.12.8/go.mod h1:uVvFidNmlt9+wa31S1urfwwthTWteBgG0hWuoKAXTx8=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.3 h1:yctD0Q3v2NOGfSWPLPvG2ggA2kV6TS6s4wioyEqssH0=
github.com/bytedance/sonic/loader v0.2.3/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
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/gin-contrib/sse v1.0.0 h1:y3bT1mUWUxDpW4JLQg/HnTqV4rozuW4tC9eFKTxYI9E=
github.com/gin-contrib/sse v1.0.0/go.mod h1:zNuFdwarAygJBht0NTKiSi3jRf6RbqeILZ9Sp6Slhe0=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
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=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg=
github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
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/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-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
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/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
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.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.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4=
golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
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/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/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=

View File

@ -0,0 +1,56 @@
package middleware
import (
"net/http"
"strings"
"users_management/m/utils/common"
"github.com/gin-gonic/gin"
)
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
common.ErrorResponses(c, http.StatusUnauthorized, "authorization token required")
c.Abort()
return
}
token = strings.TrimPrefix(token, "Bearer ")
c.Set("token", token)
req, err := http.NewRequest("POST", "https://demo.api-hrm.winteraccess.id/api/v2/auth/me", nil)
if err != nil {
common.ErrorResponses(c, http.StatusInternalServerError, err.Error())
c.Abort()
return
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
common.ErrorResponses(c, http.StatusInternalServerError, err.Error())
c.Abort()
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
common.ErrorResponses(c, http.StatusUnauthorized, "Unauthroized")
c.Abort()
return
}
c.Next()
}
}

View File

@ -7,3 +7,9 @@ type BackboneDTO struct {
DeviceEndID uuid.UUID `json:"dev_end_id"` DeviceEndID uuid.UUID `json:"dev_end_id"`
CoreAmount int `json:"core_amount"` CoreAmount int `json:"core_amount"`
} }
type UpdateBackboneDTO struct {
DeviceStartID *uuid.UUID `json:"dev_start_id,omitempty" validate:"omitempty,min=3"`
DeviceEndID *uuid.UUID `json:"dev_end_id,omitempty" validate:"omitempty,min=3"`
CoreAmount *int `json:"core_amount,omitempty" validate:"omitempty,min=1"`
}

View File

@ -1,8 +0,0 @@
package req
import "github.com/google/uuid"
type DevicePort struct {
DeviceID uuid.UUID `json:"device_id"`
PortNumber int `json:"port_number"`
}

View File

@ -0,0 +1,13 @@
package req
import "github.com/google/uuid"
type DevicePort struct {
DeviceID uuid.UUID `json:"device_id"`
PortNumber int `json:"port_number"`
}
type UpdateDevicePort struct {
DeviceID *uuid.UUID `json:"device_id,omitempty" validate:"omitempty,min=3"`
PortNumber *int `json:"port_number,omitempty" validate:"omitempty,min=1"`
}

View File

@ -9,3 +9,12 @@ type DeviceDTO struct {
PortAmount int `json:"port_amount" validate:"required"` PortAmount int `json:"port_amount" validate:"required"`
Status string `json:"status" validate:"required,oneof=active inactive maintenance"` Status string `json:"status" validate:"required,oneof=active inactive maintenance"`
} }
type UpdateDeviceDTO struct {
DeviceCode *string `json:"device_code,omitempty" validate:"omitempty,min=3"`
DeviceType *string `json:"device_type,omitempty" validate:"omitempty,min=3"`
Longitude *float64 `json:"longitude,omitempty" validate:"omitempty,longitude"`
Latitude *float64 `json:"latitude,omitempty" validate:"omitempty,latitude"`
PortAmount *int `json:"port_amount,omitempty" validate:"omitempty,min=1"`
Status *string `json:"status,omitempty" validate:"omitempty,oneof=active inactive maintenance"`
}

View File

@ -8,3 +8,10 @@ type FishboneDTO struct {
DeviceEndID uuid.UUID `json:"dev_end_id"` DeviceEndID uuid.UUID `json:"dev_end_id"`
CoreAmount int `json:"core_amount"` CoreAmount int `json:"core_amount"`
} }
type UpdateFishboneDTO struct {
BackboneID *uuid.UUID `json:"bb_id,omitempty" validate:"omitempty,min=3"`
DeviceStartID *uuid.UUID `json:"dev_start_id,omitempty" validate:"omitempty,min=3"`
DeviceEndID *uuid.UUID `json:"dev_end_id,omitempty" validate:"omitempty,min=3"`
CoreAmount *int `json:"core_amount,omitempty" validate:"omitempty,min=1"`
}

View File

@ -8,3 +8,10 @@ type TowerDTO struct {
Longitude float64 `json:"longitude"` Longitude float64 `json:"longitude"`
Latitude float64 `json:"latitude"` Latitude float64 `json:"latitude"`
} }
type UpdateTowerDTO struct {
DeviceID *string `json:"device_id,omitempty" validate:"omitempty,min=3"`
TowerCode *string `json:"tower_code,omitempty" validate:"omitempty,alphanum"`
Longitude *float64 `json:"longitude,omitempty" validate:"omitempty,longitude"`
Latitude *float64 `json:"latitude,omitempty" validate:"omitempty,latitude"`
}

View File

@ -3,13 +3,16 @@ package repository
import ( import (
"users_management/m/model/entity" "users_management/m/model/entity"
"github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
) )
type BackboneRepo interface { type BackboneRepo interface {
Post(backbone entity.Backbone) error Post(backbone entity.Backbone) error
GetAll() ([]entity.Backbone, error) GetAll() ([]entity.Backbone, error)
Update(backbone entity.Backbone) error Update(id uuid.UUID, updates map[string]interface{}) error
GetByID(id uuid.UUID) (entity.Backbone, error)
} }
type backboneRepo struct { type backboneRepo struct {
@ -32,17 +35,27 @@ func (r *backboneRepo) Post(backbone entity.Backbone) error {
func (r *backboneRepo) GetAll() ([]entity.Backbone, error) { func (r *backboneRepo) GetAll() ([]entity.Backbone, error) {
var backbones []entity.Backbone var backbones []entity.Backbone
err := r.db.Find(&backbones).Error // err := r.db.Find(&backbones).Error
err := r.db.Preload("DeviceStart").Preload("DeviceEnd").Find(&backbones).Error
if err != nil { if err != nil {
return backbones, err return backbones, err
} }
return backbones, nil return backbones, nil
} }
func (r *backboneRepo) Update(backbone entity.Backbone) error { func (r *backboneRepo) Update(id uuid.UUID, updates map[string]interface{}) error {
err := r.db.Save(&backbone).Error err := r.db.Model(&entity.Backbone{}).Where("id = ?", id).Updates(updates).Error
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (r *backboneRepo) GetByID(id uuid.UUID) (entity.Backbone, error) {
var backbone entity.Backbone
err := r.db.Where("id = ?", id).Preload("DeviceStart").Preload("DeviceEnd").First(&backbone).Error
if err != nil {
return backbone, err
}
return backbone, nil
}

View File

@ -3,13 +3,16 @@ package repository
import ( import (
"users_management/m/model/entity" "users_management/m/model/entity"
"github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
) )
type DevicePortRepo interface { type DevicePortRepo interface {
Post(devicePort entity.DevicePort) error Post(devicePort entity.DevicePort) error
GetAll() ([]entity.DevicePort, error) GetAll() ([]entity.DevicePort, error)
Update(devicePort entity.DevicePort) error Update(id uuid.UUID, updates map[string]interface{}) error
GetByID(id uuid.UUID) (entity.DevicePort, error)
} }
type devicePortRepo struct { type devicePortRepo struct {
@ -32,17 +35,27 @@ func (r *devicePortRepo) Post(devicePort entity.DevicePort) error {
func (r *devicePortRepo) GetAll() ([]entity.DevicePort, error) { func (r *devicePortRepo) GetAll() ([]entity.DevicePort, error) {
var devicePorts []entity.DevicePort var devicePorts []entity.DevicePort
err := r.db.Find(&devicePorts).Error err := r.db.Preload("Device").Find(&devicePorts).Error
if err != nil { if err != nil {
return devicePorts, err return devicePorts, err
} }
return devicePorts, nil return devicePorts, nil
} }
func (r *devicePortRepo) Update(devicePort entity.DevicePort) error { func (r *devicePortRepo) Update(id uuid.UUID,updates map[string]interface{}) error {
err := r.db.Save(&devicePort).Error err := r.db.Model(&entity.DevicePort{}).Where("id = ?", id).Updates(updates).Error
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (r *devicePortRepo) GetByID(id uuid.UUID) (entity.DevicePort, error) {
var devicePort entity.DevicePort
err := r.db.Where("id = ?", id).Preload("Device").First(&devicePort).Error
if err != nil {
return devicePort, err
}
return devicePort, nil
}

View File

@ -3,13 +3,16 @@ package repository
import ( import (
"users_management/m/model/entity" "users_management/m/model/entity"
"github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
) )
type DevicesRepo interface { type DevicesRepo interface {
Post(device entity.Device) error Post(device entity.Device) error
GetAll() ([]entity.Device, error) GetAll() ([]entity.Device, error)
Update(device entity.Device) error Update(id uuid.UUID,updates map[string]interface{}) error
GetByID(id uuid.UUID) (entity.Device, error)
} }
type devicesRepo struct { type devicesRepo struct {
@ -38,10 +41,19 @@ func (r *devicesRepo) GetAll() ([]entity.Device, error) {
} }
return devices, nil return devices, nil
} }
func (r *devicesRepo) Update(device entity.Device) error { func (r *devicesRepo) Update(id uuid.UUID,updates map[string]interface{}) error {
err := r.db.Save(&device).Error err := r.db.Model(&entity.Device{}).Where("id = ?", id).Updates(updates).Error
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (r *devicesRepo) GetByID(id uuid.UUID) (entity.Device, error) {
var device entity.Device
err := r.db.Where("id = ?", id).First(&device).Error
if err != nil {
return device, err
}
return device, nil
}

View File

@ -3,13 +3,16 @@ package repository
import ( import (
"users_management/m/model/entity" "users_management/m/model/entity"
"github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
) )
type FishboneRepo interface { type FishboneRepo interface {
Post(fishbone entity.Fishbone) error Post(fishbone entity.Fishbone) error
GetAll() ([]entity.Fishbone, error) GetAll() ([]entity.Fishbone, error)
Update(fishbone entity.Fishbone) error Update(id uuid.UUID,updates map[string]interface{}) error
GetByID(id uuid.UUID) (entity.Fishbone, error)
} }
type fishboneRepo struct { type fishboneRepo struct {
@ -32,17 +35,26 @@ func (r *fishboneRepo) Post(fishbone entity.Fishbone) error {
func (r *fishboneRepo) GetAll() ([]entity.Fishbone, error) { func (r *fishboneRepo) GetAll() ([]entity.Fishbone, error) {
var fishbones []entity.Fishbone var fishbones []entity.Fishbone
err := r.db.Find(&fishbones).Error err := r.db.Preload("DeviceStart").Preload("DeviceEnd").Preload("Backbone").Preload("Backbone.DeviceStart").Preload("Backbone.DeviceEnd").Find(&fishbones).Error
if err != nil { if err != nil {
return fishbones, err return fishbones, err
} }
return fishbones, nil return fishbones, nil
} }
func (r *fishboneRepo) Update(fishbone entity.Fishbone) error { func (r *fishboneRepo) Update(id uuid.UUID,updates map[string]interface{}) error {
err := r.db.Save(&fishbone).Error err := r.db.Model(&entity.Fishbone{}).Where("id = ?", id).Updates(updates).Error
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (r *fishboneRepo) GetByID(id uuid.UUID) (entity.Fishbone, error) {
var fishbone entity.Fishbone
err := r.db.Where("id = ?", id).Preload("DeviceStart").Preload("DeviceEnd").Preload("Backbone.DeviceStart").Preload("Backbone.DeviceEnd").First(&fishbone).Error
if err != nil {
return fishbone, err
}
return fishbone, nil
}

View File

@ -3,13 +3,15 @@ package repository
import ( import (
"users_management/m/model/entity" "users_management/m/model/entity"
"github.com/google/uuid"
"gorm.io/gorm" "gorm.io/gorm"
) )
type TowerRepo interface { type TowerRepo interface {
Post(tower entity.Tower) error Post(tower entity.Tower) error
GetAll() ([]entity.Tower, error) GetAll() ([]entity.Tower, error)
Update(tower entity.Tower) error Update(id uuid.UUID,updates map[string]interface{}) error
GetByID(id uuid.UUID) (entity.Tower, error)
} }
type towerRepo struct { type towerRepo struct {
@ -32,17 +34,26 @@ func (r *towerRepo) Post(tower entity.Tower) error {
func (r *towerRepo) GetAll() ([]entity.Tower, error) { func (r *towerRepo) GetAll() ([]entity.Tower, error) {
var towers []entity.Tower var towers []entity.Tower
err := r.db.Find(&towers).Error err := r.db.Preload("Device").Find(&towers).Error
if err != nil { if err != nil {
return towers, err return towers, err
} }
return towers, nil return towers, nil
} }
func (r *towerRepo) Update(tower entity.Tower) error { func (r *towerRepo) Update(id uuid.UUID,updates map[string]interface{}) error {
err := r.db.Save(&tower).Error err := r.db.Model(&entity.Tower{}).Where("id = ?", id).Updates(updates).Error
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
func (r *towerRepo) GetByID(id uuid.UUID) (entity.Tower, error) {
var tower entity.Tower
err := r.db.Where("id = ?", id).Preload("Device").First(&tower).Error
if err != nil {
return tower, err
}
return tower, nil
}

View File

@ -14,6 +14,9 @@ import (
type BackboneUseCase interface { type BackboneUseCase interface {
CreateBackbone(backbone req.BackboneDTO) error CreateBackbone(backbone req.BackboneDTO) error
GetAllBackbone() ([]entity.Backbone, error) GetAllBackbone() ([]entity.Backbone, error)
GetByID(id uuid.UUID) (entity.Backbone, error)
UpdateBackbone(id uuid.UUID, backbone req.UpdateBackboneDTO) error
} }
type backboneUseCase struct { type backboneUseCase struct {
@ -54,3 +57,36 @@ func (u *backboneUseCase) GetAllBackbone() ([]entity.Backbone, error) {
} }
return backbones, nil return backbones, nil
} }
func (u *backboneUseCase) GetByID(id uuid.UUID) (entity.Backbone, error) {
backbone, err := u.backboneRepo.GetByID(id)
if err != nil {
return backbone, err
}
return backbone, nil
}
func (u *backboneUseCase) UpdateBackbone(id uuid.UUID, backbone req.UpdateBackboneDTO) error {
err := u.validate.Struct(backbone)
if err != nil {
return fmt.Errorf("validation error: %w", err)
}
updates := make(map[string]interface{})
if backbone.DeviceStartID != nil {
updates["DeviceStartID"] = backbone.DeviceStartID
}
if backbone.DeviceEndID != nil {
updates["DeviceEndID"] = backbone.DeviceEndID
}
if backbone.CoreAmount != nil {
updates["CoreAmount"] = backbone.CoreAmount
}
updates["UpdatedAt"] = time.Now()
return u.backboneRepo.Update(id, updates)
}

View File

@ -13,6 +13,9 @@ import (
type DevicePortUseCase interface { type DevicePortUseCase interface {
CreateDevicePort(devicePort req.DevicePort) error CreateDevicePort(devicePort req.DevicePort) error
GetAllDevicePort() ([]entity.DevicePort, error) GetAllDevicePort() ([]entity.DevicePort, error)
GetByID(id uuid.UUID) (entity.DevicePort, error)
UpdateDevicePort(id uuid.UUID, devicePort req.UpdateDevicePort) error
} }
type devicePortUseCase struct { type devicePortUseCase struct {
@ -51,3 +54,33 @@ func (u *devicePortUseCase) GetAllDevicePort() ([]entity.DevicePort, error) {
} }
return devicePorts, nil return devicePorts, nil
} }
func (u *devicePortUseCase) GetByID(id uuid.UUID) (entity.DevicePort, error) {
devicePort, err := u.devicePortRepo.GetByID(id)
if err != nil {
return devicePort, err
}
return devicePort, nil
}
func (u *devicePortUseCase) UpdateDevicePort(id uuid.UUID, devicePort req.UpdateDevicePort) error {
err := u.validate.Struct(devicePort)
if err != nil {
return err
}
updates := make(map[string]interface{})
if devicePort.DeviceID != nil {
updates["DeviceID"] = *devicePort.DeviceID
}
if devicePort.PortNumber != nil {
updates["PortNumber"] = *devicePort.PortNumber
}
updates["UpdatedAt"] = time.Now()
return u.devicePortRepo.Update(id, updates)
}

View File

@ -14,6 +14,9 @@ import (
type DeviceUseCase interface { type DeviceUseCase interface {
CreateDevice(device req.DeviceDTO) error CreateDevice(device req.DeviceDTO) error
GetAllDevices() ([]entity.Device, error) GetAllDevices() ([]entity.Device, error)
GetByID(id uuid.UUID) (entity.Device, error)
UpdateDevice(id uuid.UUID, device req.UpdateDeviceDTO) error
} }
type deviceUseCase struct { type deviceUseCase struct {
@ -56,3 +59,44 @@ func (u *deviceUseCase) GetAllDevices() ([]entity.Device, error) {
} }
return devices, nil return devices, nil
} }
func (u *deviceUseCase) GetByID(id uuid.UUID) (entity.Device, error) {
device, err := u.deviceRepo.GetByID(id)
if err != nil {
return device, err
}
return device, nil
}
func (u *deviceUseCase) UpdateDevice(id uuid.UUID, device req.UpdateDeviceDTO) error {
err := u.validate.Struct(device)
if err != nil {
return fmt.Errorf("validation error: %w", err)
}
updates := map[string]interface{}{}
if device.DeviceCode != nil {
updates["DeviceCode"] = *device.DeviceCode
}
if device.DeviceType != nil {
updates["DeviceType"] = *device.DeviceType
}
if device.Longitude != nil {
updates["Longitude"] = *device.Longitude
}
if device.Latitude != nil {
updates["Latitude"] = *device.Latitude
}
if device.PortAmount != nil {
updates["PortAmount"] = *device.PortAmount
}
if len(updates) == 0 {
return fmt.Errorf("no update data")
}
updates["UpdatedAt"] = time.Now()
return u.deviceRepo.Update(id, updates)
}

View File

@ -1,6 +1,7 @@
package usecase package usecase
import ( import (
"errors"
"time" "time"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/model/entity" "users_management/m/model/entity"
@ -13,6 +14,9 @@ import (
type FishboneUseCase interface { type FishboneUseCase interface {
CreateFishbone(fishbone req.FishboneDTO) error CreateFishbone(fishbone req.FishboneDTO) error
GetAllFishbone() ([]entity.Fishbone, error) GetAllFishbone() ([]entity.Fishbone, error)
GetByID(id uuid.UUID) (entity.Fishbone, error)
UpdateFishbone(id uuid.UUID, fishbone req.UpdateFishboneDTO) error
} }
type fishboneUsecase struct { type fishboneUsecase struct {
@ -53,3 +57,40 @@ func (u *fishboneUsecase) GetAllFishbone() ([]entity.Fishbone, error) {
} }
return fishbones, nil return fishbones, nil
} }
func (u *fishboneUsecase) GetByID(id uuid.UUID) (entity.Fishbone, error) {
fishbone, err := u.fishboneRepo.GetByID(id)
if err != nil {
return fishbone, err
}
return fishbone, nil
}
func (u *fishboneUsecase) UpdateFishbone(id uuid.UUID, fishbone req.UpdateFishboneDTO) error {
err := u.validate.Struct(fishbone)
if err != nil {
return err
}
updates := make(map[string]interface{})
if fishbone.BackboneID != nil {
updates["BackboneID"] = *fishbone.BackboneID
}
if fishbone.DeviceStartID != nil {
updates["DeviceStartID"] = *fishbone.DeviceStartID
}
if fishbone.DeviceEndID != nil {
updates["DeviceEndID"] = *fishbone.DeviceEndID
}
if fishbone.CoreAmount != nil {
updates["CoreAmount"] = *fishbone.CoreAmount
}
if len(updates) == 0 {
return errors.New("no fields to update")
}
updates["UpdatedAt"] = time.Now()
return u.fishboneRepo.Update(id, updates)
}

View File

@ -1,6 +1,7 @@
package usecase package usecase
import ( import (
"errors"
"time" "time"
"users_management/m/model/dto/req" "users_management/m/model/dto/req"
"users_management/m/model/entity" "users_management/m/model/entity"
@ -13,6 +14,8 @@ import (
type TowerUseCase interface { type TowerUseCase interface {
Post(tower req.TowerDTO) error Post(tower req.TowerDTO) error
GetAll() ([]entity.Tower, error) GetAll() ([]entity.Tower, error)
GetByID(id uuid.UUID) (entity.Tower, error)
UpdateTower(id uuid.UUID, tower req.UpdateTowerDTO) error
} }
type towerUsecase struct { type towerUsecase struct {
@ -53,3 +56,42 @@ func (u *towerUsecase) GetAll() ([]entity.Tower, error) {
} }
return towers, nil return towers, nil
} }
func (u *towerUsecase) GetByID(id uuid.UUID) (entity.Tower, error) {
tower, err := u.towerRepo.GetByID(id)
if err != nil {
return tower, err
}
return tower, nil
}
func (u *towerUsecase) UpdateTower(id uuid.UUID, tower req.UpdateTowerDTO) error {
err := u.validate.Struct(tower)
if err != nil {
return err // Return validation error
}
updates := make(map[string]interface{})
if tower.DeviceID != nil {
updates["DeviceID"] = *tower.DeviceID
}
if tower.TowerCode != nil {
updates["TowerCode"] = *tower.TowerCode
}
if tower.Longitude != nil {
updates["Longitude"] = *tower.Longitude
}
if tower.Latitude != nil {
updates["Latitude"] = *tower.Latitude
}
// If no fields are updated, return an error
if len(updates) == 0 {
return errors.New("no fields to update")
}
updates["UpdatedAt"] = time.Now()
return u.towerRepo.Update(id, updates)
}