mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'dev/hafizh' into 'development'
chore: adjust docker and any file for starting project See merge request mbugroup/lti-api!3
This commit is contained in:
+10
-15
@@ -1,5 +1,6 @@
|
|||||||
# server configuration
|
# server configuration
|
||||||
# Env value : prod || dev
|
# Env value : prod || dev
|
||||||
|
VERSION=0.0.1
|
||||||
APP_ENV=dev
|
APP_ENV=dev
|
||||||
APP_HOST=0.0.0.0
|
APP_HOST=0.0.0.0
|
||||||
APP_PORT=8080
|
APP_PORT=8080
|
||||||
@@ -13,25 +14,19 @@ DB_NAME=db_lti_erp
|
|||||||
DB_PORT=5432
|
DB_PORT=5432
|
||||||
|
|
||||||
# JWT
|
# JWT
|
||||||
# JWT secret key
|
|
||||||
JWT_SECRET=changeme
|
JWT_SECRET=changeme
|
||||||
# Number of minutes after which an access token expires
|
|
||||||
JWT_ACCESS_EXP_MINUTES=30
|
JWT_ACCESS_EXP_MINUTES=30
|
||||||
# Number of days after which a refresh token expires
|
|
||||||
JWT_REFRESH_EXP_DAYS=30
|
JWT_REFRESH_EXP_DAYS=30
|
||||||
# Number of minutes after which a reset password token expires
|
|
||||||
JWT_RESET_PASSWORD_EXP_MINUTES=10
|
JWT_RESET_PASSWORD_EXP_MINUTES=10
|
||||||
# Number of minutes after which a verify email token expires
|
|
||||||
JWT_VERIFY_EMAIL_EXP_MINUTES=10
|
JWT_VERIFY_EMAIL_EXP_MINUTES=10
|
||||||
|
|
||||||
# SMTP configuration options for the email service
|
# CORS
|
||||||
SMTP_HOST=email-server
|
CORS_ALLOW_ORIGINS=changeme
|
||||||
SMTP_PORT=587
|
CORS_ALLOW_METHODS=GET,POST,PUT,PATCH,DELETE,OPTIONS
|
||||||
SMTP_USERNAME=email-server-username
|
CORS_ALLOW_HEADERS=Authorization,Content-Type,X-Requested-With
|
||||||
SMTP_PASSWORD=changeme
|
CORS_EXPOSE_HEADERS=Link,Location
|
||||||
EMAIL_FROM=support@yourapp.com
|
CORS_ALLOW_CREDENTIALS=true
|
||||||
|
CORS_MAX_AGE=600
|
||||||
|
|
||||||
# OAuth2 configuration
|
# Redis
|
||||||
GOOGLE_CLIENT_ID=yourapps.googleusercontent.com
|
REDIS_URL=redis://redis:6379/0
|
||||||
GOOGLE_CLIENT_SECRET=changeme
|
|
||||||
REDIRECT_URL=http://localhost:3000/v1/auth/google-callback
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ bin/
|
|||||||
*.exe
|
*.exe
|
||||||
*.out
|
*.out
|
||||||
|
|
||||||
|
# Go build cache
|
||||||
|
.gocache/
|
||||||
|
|
||||||
# Logs & reports
|
# Logs & reports
|
||||||
*.log
|
*.log
|
||||||
*.txt
|
*.txt
|
||||||
|
|||||||
+200
-343
@@ -1,346 +1,203 @@
|
|||||||
# ## Config for golangci-lint v1.60.1
|
## Config for golangci-lint v2 schema
|
||||||
|
version: "2"
|
||||||
|
|
||||||
# run:
|
run:
|
||||||
# # Timeout for analysis, e.g. 30s, 5m.
|
timeout: 3m
|
||||||
# # Default: 1m
|
|
||||||
# timeout: 3m
|
|
||||||
|
|
||||||
# # This file contains only configs which differ from defaults.
|
linters:
|
||||||
# # All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
|
default: none
|
||||||
# linters-settings:
|
enable:
|
||||||
# cyclop:
|
## enabled by default
|
||||||
# # The maximal code complexity to report.
|
- errcheck
|
||||||
# # Default: 10
|
- govet
|
||||||
# max-complexity: 30
|
- ineffassign
|
||||||
# # The maximal average package complexity.
|
- staticcheck
|
||||||
# # If it's higher than 0.0 (float) the check is enabled
|
- unused
|
||||||
# # Default: 0.0
|
## disabled by default
|
||||||
# package-average: 10.0
|
- asasalint
|
||||||
|
- asciicheck
|
||||||
|
- bidichk
|
||||||
|
- bodyclose
|
||||||
|
- canonicalheader
|
||||||
|
- cyclop
|
||||||
|
- dupl
|
||||||
|
- durationcheck
|
||||||
|
- errname
|
||||||
|
- errorlint
|
||||||
|
- exhaustive
|
||||||
|
- fatcontext
|
||||||
|
- forbidigo
|
||||||
|
- funlen
|
||||||
|
- gocheckcompilerdirectives
|
||||||
|
#- gochecknoglobals
|
||||||
|
#- gochecknoinits
|
||||||
|
- gochecksumtype
|
||||||
|
- gocognit
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
#- godot
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- intrange
|
||||||
|
- lll
|
||||||
|
- loggercheck
|
||||||
|
- makezero
|
||||||
|
- mirror
|
||||||
|
#- mnd
|
||||||
|
- musttag
|
||||||
|
- nakedret
|
||||||
|
- nestif
|
||||||
|
- nilerr
|
||||||
|
- nilnil
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- nonamedreturns
|
||||||
|
- nosprintfhostport
|
||||||
|
- perfsprint
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- protogetter
|
||||||
|
- reassign
|
||||||
|
- revive
|
||||||
|
- rowserrcheck
|
||||||
|
- sloglint
|
||||||
|
- spancheck
|
||||||
|
- sqlclosecheck
|
||||||
|
- testableexamples
|
||||||
|
#- testifylint
|
||||||
|
- testpackage
|
||||||
|
- tparallel
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- usestdlibvars
|
||||||
|
- usetesting
|
||||||
|
- wastedassign
|
||||||
|
- whitespace
|
||||||
|
settings:
|
||||||
|
cyclop:
|
||||||
|
max-complexity: 30
|
||||||
|
package-average: 10.0
|
||||||
|
errcheck:
|
||||||
|
check-type-assertions: true
|
||||||
|
exhaustive:
|
||||||
|
check:
|
||||||
|
- switch
|
||||||
|
- map
|
||||||
|
exhaustruct:
|
||||||
|
exclude:
|
||||||
|
- "^net/http.Client$"
|
||||||
|
- "^net/http.Cookie$"
|
||||||
|
- "^net/http.Request$"
|
||||||
|
- "^net/http.Response$"
|
||||||
|
- "^net/http.Server$"
|
||||||
|
- "^net/http.Transport$"
|
||||||
|
- "^net/url.URL$"
|
||||||
|
- "^os/exec.Cmd$"
|
||||||
|
- "^reflect.StructField$"
|
||||||
|
- "^github.com/Shopify/sarama.Config$"
|
||||||
|
- "^github.com/Shopify/sarama.ProducerMessage$"
|
||||||
|
- "^github.com/mitchellh/mapstructure.DecoderConfig$"
|
||||||
|
- "^github.com/prometheus/client_golang/.+Opts$"
|
||||||
|
- "^github.com/spf13/cobra.Command$"
|
||||||
|
- "^github.com/spf13/cobra.CompletionOptions$"
|
||||||
|
- "^github.com/stretchr/testify/mock.Mock$"
|
||||||
|
- "^github.com/testcontainers/testcontainers-go.+Request$"
|
||||||
|
- "^github.com/testcontainers/testcontainers-go.FromDockerfile$"
|
||||||
|
- "^golang.org/x/tools/go/analysis.Analyzer$"
|
||||||
|
- "^google.golang.org/protobuf/.+Options$"
|
||||||
|
- "^gopkg.in/yaml.v3.Node$"
|
||||||
|
funlen:
|
||||||
|
lines: 100
|
||||||
|
statements: 50
|
||||||
|
ignore-comments: true
|
||||||
|
gocognit:
|
||||||
|
min-complexity: 20
|
||||||
|
gocritic:
|
||||||
|
settings:
|
||||||
|
captLocal:
|
||||||
|
paramsOnly: false
|
||||||
|
underef:
|
||||||
|
skipRecvDeref: false
|
||||||
|
gomodguard:
|
||||||
|
blocked:
|
||||||
|
modules:
|
||||||
|
- github.com/golang/protobuf:
|
||||||
|
recommendations:
|
||||||
|
- google.golang.org/protobuf
|
||||||
|
reason: "see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules"
|
||||||
|
- github.com/satori/go.uuid:
|
||||||
|
recommendations:
|
||||||
|
- github.com/google/uuid
|
||||||
|
reason: "satori's package is not maintained"
|
||||||
|
- github.com/gofrs/uuid:
|
||||||
|
recommendations:
|
||||||
|
- github.com/gofrs/uuid/v5
|
||||||
|
reason: "gofrs' package was not go module before v5"
|
||||||
|
govet:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- fieldalignment
|
||||||
|
settings:
|
||||||
|
shadow:
|
||||||
|
strict: true
|
||||||
|
inamedparam:
|
||||||
|
skip-single-param: true
|
||||||
|
mnd:
|
||||||
|
ignored-functions:
|
||||||
|
- args.Error
|
||||||
|
- flag.Arg
|
||||||
|
- flag.Duration.*
|
||||||
|
- flag.Float.*
|
||||||
|
- flag.Int.*
|
||||||
|
- flag.Uint.*
|
||||||
|
- os.Chmod
|
||||||
|
- os.Mkdir.*
|
||||||
|
- os.OpenFile
|
||||||
|
- os.WriteFile
|
||||||
|
- prometheus.ExponentialBuckets.*
|
||||||
|
- prometheus.LinearBuckets
|
||||||
|
nakedret:
|
||||||
|
max-func-lines: 0
|
||||||
|
nolintlint:
|
||||||
|
allow-no-explanation:
|
||||||
|
- funlen
|
||||||
|
- gocognit
|
||||||
|
- lll
|
||||||
|
require-explanation: true
|
||||||
|
require-specific: true
|
||||||
|
perfsprint:
|
||||||
|
strconcat: false
|
||||||
|
rowserrcheck:
|
||||||
|
packages:
|
||||||
|
- github.com/jmoiron/sqlx
|
||||||
|
sloglint:
|
||||||
|
no-global: "all"
|
||||||
|
context: "scope"
|
||||||
|
exclusions:
|
||||||
|
rules:
|
||||||
|
- source: "(noinspection|TODO)"
|
||||||
|
linters:
|
||||||
|
- godot
|
||||||
|
- source: "//noinspection"
|
||||||
|
linters:
|
||||||
|
- gocritic
|
||||||
|
- path: "example\\.go"
|
||||||
|
linters:
|
||||||
|
- lll
|
||||||
|
- path: "_test\\.go"
|
||||||
|
linters:
|
||||||
|
- bodyclose
|
||||||
|
- dupl
|
||||||
|
- funlen
|
||||||
|
- goconst
|
||||||
|
- gosec
|
||||||
|
- noctx
|
||||||
|
- wrapcheck
|
||||||
|
- lll
|
||||||
|
- testpackage
|
||||||
|
|
||||||
# errcheck:
|
issues:
|
||||||
# # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
|
max-same-issues: 50
|
||||||
# # Such cases aren't reported by default.
|
|
||||||
# # Default: false
|
|
||||||
# check-type-assertions: true
|
|
||||||
|
|
||||||
# exhaustive:
|
|
||||||
# # Program elements to check for exhaustiveness.
|
|
||||||
# # Default: [ switch ]
|
|
||||||
# check:
|
|
||||||
# - switch
|
|
||||||
# - map
|
|
||||||
|
|
||||||
# exhaustruct:
|
|
||||||
# # List of regular expressions to exclude struct packages and their names from checks.
|
|
||||||
# # Regular expressions must match complete canonical struct package/name/structname.
|
|
||||||
# # Default: []
|
|
||||||
# exclude:
|
|
||||||
# # std libs
|
|
||||||
# - "^net/http.Client$"
|
|
||||||
# - "^net/http.Cookie$"
|
|
||||||
# - "^net/http.Request$"
|
|
||||||
# - "^net/http.Response$"
|
|
||||||
# - "^net/http.Server$"
|
|
||||||
# - "^net/http.Transport$"
|
|
||||||
# - "^net/url.URL$"
|
|
||||||
# - "^os/exec.Cmd$"
|
|
||||||
# - "^reflect.StructField$"
|
|
||||||
# # public libs
|
|
||||||
# - "^github.com/Shopify/sarama.Config$"
|
|
||||||
# - "^github.com/Shopify/sarama.ProducerMessage$"
|
|
||||||
# - "^github.com/mitchellh/mapstructure.DecoderConfig$"
|
|
||||||
# - "^github.com/prometheus/client_golang/.+Opts$"
|
|
||||||
# - "^github.com/spf13/cobra.Command$"
|
|
||||||
# - "^github.com/spf13/cobra.CompletionOptions$"
|
|
||||||
# - "^github.com/stretchr/testify/mock.Mock$"
|
|
||||||
# - "^github.com/testcontainers/testcontainers-go.+Request$"
|
|
||||||
# - "^github.com/testcontainers/testcontainers-go.FromDockerfile$"
|
|
||||||
# - "^golang.org/x/tools/go/analysis.Analyzer$"
|
|
||||||
# - "^google.golang.org/protobuf/.+Options$"
|
|
||||||
# - "^gopkg.in/yaml.v3.Node$"
|
|
||||||
|
|
||||||
# funlen:
|
|
||||||
# # Checks the number of lines in a function.
|
|
||||||
# # If lower than 0, disable the check.
|
|
||||||
# # Default: 60
|
|
||||||
# lines: 100
|
|
||||||
# # Checks the number of statements in a function.
|
|
||||||
# # If lower than 0, disable the check.
|
|
||||||
# # Default: 40
|
|
||||||
# statements: 50
|
|
||||||
# # Ignore comments when counting lines.
|
|
||||||
# # Default false
|
|
||||||
# ignore-comments: true
|
|
||||||
|
|
||||||
# gocognit:
|
|
||||||
# # Minimal code complexity to report.
|
|
||||||
# # Default: 30 (but we recommend 10-20)
|
|
||||||
# min-complexity: 20
|
|
||||||
|
|
||||||
# gocritic:
|
|
||||||
# # Settings passed to gocritic.
|
|
||||||
# # The settings key is the name of a supported gocritic checker.
|
|
||||||
# # The list of supported checkers can be find in https://go-critic.github.io/overview.
|
|
||||||
# settings:
|
|
||||||
# captLocal:
|
|
||||||
# # Whether to restrict checker to params only.
|
|
||||||
# # Default: true
|
|
||||||
# paramsOnly: false
|
|
||||||
# underef:
|
|
||||||
# # Whether to skip (*x).method() calls where x is a pointer receiver.
|
|
||||||
# # Default: true
|
|
||||||
# skipRecvDeref: false
|
|
||||||
|
|
||||||
# gomodguard:
|
|
||||||
# blocked:
|
|
||||||
# # List of blocked modules.
|
|
||||||
# # Default: []
|
|
||||||
# modules:
|
|
||||||
# - github.com/golang/protobuf:
|
|
||||||
# recommendations:
|
|
||||||
# - google.golang.org/protobuf
|
|
||||||
# reason: "see https://developers.google.com/protocol-buffers/docs/reference/go/faq#modules"
|
|
||||||
# - github.com/satori/go.uuid:
|
|
||||||
# recommendations:
|
|
||||||
# - github.com/google/uuid
|
|
||||||
# reason: "satori's package is not maintained"
|
|
||||||
# - github.com/gofrs/uuid:
|
|
||||||
# recommendations:
|
|
||||||
# - github.com/gofrs/uuid/v5
|
|
||||||
# reason: "gofrs' package was not go module before v5"
|
|
||||||
|
|
||||||
# govet:
|
|
||||||
# # Enable all analyzers.
|
|
||||||
# # Default: false
|
|
||||||
# enable-all: true
|
|
||||||
# # Disable analyzers by name.
|
|
||||||
# # Run `go tool vet help` to see all analyzers.
|
|
||||||
# # Default: []
|
|
||||||
# disable:
|
|
||||||
# - fieldalignment # too strict
|
|
||||||
# # Settings per analyzer.
|
|
||||||
# settings:
|
|
||||||
# shadow:
|
|
||||||
# # Whether to be strict about shadowing; can be noisy.
|
|
||||||
# # Default: false
|
|
||||||
# strict: true
|
|
||||||
|
|
||||||
# inamedparam:
|
|
||||||
# # Skips check for interface methods with only a single parameter.
|
|
||||||
# # Default: false
|
|
||||||
# skip-single-param: true
|
|
||||||
|
|
||||||
# mnd:
|
|
||||||
# # List of function patterns to exclude from analysis.
|
|
||||||
# # Values always ignored: `time.Date`,
|
|
||||||
# # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,
|
|
||||||
# # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.
|
|
||||||
# # Default: []
|
|
||||||
# ignored-functions:
|
|
||||||
# - args.Error
|
|
||||||
# - flag.Arg
|
|
||||||
# - flag.Duration.*
|
|
||||||
# - flag.Float.*
|
|
||||||
# - flag.Int.*
|
|
||||||
# - flag.Uint.*
|
|
||||||
# - os.Chmod
|
|
||||||
# - os.Mkdir.*
|
|
||||||
# - os.OpenFile
|
|
||||||
# - os.WriteFile
|
|
||||||
# - prometheus.ExponentialBuckets.*
|
|
||||||
# - prometheus.LinearBuckets
|
|
||||||
|
|
||||||
# nakedret:
|
|
||||||
# # Make an issue if func has more lines of code than this setting, and it has naked returns.
|
|
||||||
# # Default: 30
|
|
||||||
# max-func-lines: 0
|
|
||||||
|
|
||||||
# nolintlint:
|
|
||||||
# # Exclude following linters from requiring an explanation.
|
|
||||||
# # Default: []
|
|
||||||
# allow-no-explanation: [funlen, gocognit, lll]
|
|
||||||
# # Enable to require an explanation of nonzero length after each nolint directive.
|
|
||||||
# # Default: false
|
|
||||||
# require-explanation: true
|
|
||||||
# # Enable to require nolint directives to mention the specific linter being suppressed.
|
|
||||||
# # Default: false
|
|
||||||
# require-specific: true
|
|
||||||
|
|
||||||
# perfsprint:
|
|
||||||
# # Optimizes into strings concatenation.
|
|
||||||
# # Default: true
|
|
||||||
# strconcat: false
|
|
||||||
|
|
||||||
# rowserrcheck:
|
|
||||||
# # database/sql is always checked
|
|
||||||
# # Default: []
|
|
||||||
# packages:
|
|
||||||
# - github.com/jmoiron/sqlx
|
|
||||||
|
|
||||||
# sloglint:
|
|
||||||
# # Enforce not using global loggers.
|
|
||||||
# # Values:
|
|
||||||
# # - "": disabled
|
|
||||||
# # - "all": report all global loggers
|
|
||||||
# # - "default": report only the default slog logger
|
|
||||||
# # https://github.com/go-simpler/sloglint?tab=readme-ov-file#no-global
|
|
||||||
# # Default: ""
|
|
||||||
# no-global: "all"
|
|
||||||
# # Enforce using methods that accept a context.
|
|
||||||
# # Values:
|
|
||||||
# # - "": disabled
|
|
||||||
# # - "all": report all contextless calls
|
|
||||||
# # - "scope": report only if a context exists in the scope of the outermost function
|
|
||||||
# # https://github.com/go-simpler/sloglint?tab=readme-ov-file#context-only
|
|
||||||
# # Default: ""
|
|
||||||
# context: "scope"
|
|
||||||
|
|
||||||
# tenv:
|
|
||||||
# # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
|
|
||||||
# # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
|
|
||||||
# # Default: false
|
|
||||||
# all: true
|
|
||||||
|
|
||||||
# linters:
|
|
||||||
# disable-all: true
|
|
||||||
# enable:
|
|
||||||
# ## enabled by default
|
|
||||||
# - errcheck # checking for unchecked errors, these unchecked errors can be critical bugs in some cases
|
|
||||||
# - gosimple # specializes in simplifying a code
|
|
||||||
# - govet # reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
|
|
||||||
# - ineffassign # detects when assignments to existing variables are not used
|
|
||||||
# - staticcheck # is a go vet on steroids, applying a ton of static analysis checks
|
|
||||||
# - typecheck # like the front-end of a Go compiler, parses and type-checks Go code
|
|
||||||
# - unused # checks for unused constants, variables, functions and types
|
|
||||||
# ## disabled by default
|
|
||||||
# - asasalint # checks for pass []any as any in variadic func(...any)
|
|
||||||
# - asciicheck # checks that your code does not contain non-ASCII identifiers
|
|
||||||
# - bidichk # checks for dangerous unicode character sequences
|
|
||||||
# - bodyclose # checks whether HTTP response body is closed successfully
|
|
||||||
# - canonicalheader # checks whether net/http.Header uses canonical header
|
|
||||||
# - cyclop # checks function and package cyclomatic complexity
|
|
||||||
# - dupl # tool for code clone detection
|
|
||||||
# - durationcheck # checks for two durations multiplied together
|
|
||||||
# - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error
|
|
||||||
# - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13
|
|
||||||
# - exhaustive # checks exhaustiveness of enum switch statements
|
|
||||||
# - fatcontext # detects nested contexts in loops
|
|
||||||
# - forbidigo # forbids identifiers
|
|
||||||
# - funlen # tool for detection of long functions
|
|
||||||
# - gocheckcompilerdirectives # validates go compiler directive comments (//go:)
|
|
||||||
# #- gochecknoglobals # checks that no global variables exist
|
|
||||||
# #- gochecknoinits # checks that no init functions are present in Go code
|
|
||||||
# - gochecksumtype # checks exhaustiveness on Go "sum types"
|
|
||||||
# - gocognit # computes and checks the cognitive complexity of functions
|
|
||||||
# - goconst # finds repeated strings that could be replaced by a constant
|
|
||||||
# - gocritic # provides diagnostics that check for bugs, performance and style issues
|
|
||||||
# - gocyclo # computes and checks the cyclomatic complexity of functions
|
|
||||||
# #- godot # checks if comments end in a period
|
|
||||||
# - goimports # in addition to fixing imports, goimports also formats your code in the same style as gofmt
|
|
||||||
# - gomoddirectives # manages the use of 'replace', 'retract', and 'excludes' directives in go.mod
|
|
||||||
# - gomodguard # allow and block lists linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations
|
|
||||||
# - goprintffuncname # checks that printf-like functions are named with f at the end
|
|
||||||
# - gosec # inspects source code for security problems
|
|
||||||
# - intrange # finds places where for loops could make use of an integer range
|
|
||||||
# - lll # reports long lines
|
|
||||||
# - loggercheck # checks key value pairs for common logger libraries (kitlog,klog,logr,zap)
|
|
||||||
# - makezero # finds slice declarations with non-zero initial length
|
|
||||||
# - mirror # reports wrong mirror patterns of bytes/strings usage
|
|
||||||
# #- mnd # detects magic numbers
|
|
||||||
# - musttag # enforces field tags in (un)marshaled structs
|
|
||||||
# - nakedret # finds naked returns in functions greater than a specified function length
|
|
||||||
# - nestif # reports deeply nested if statements
|
|
||||||
# - nilerr # finds the code that returns nil even if it checks that the error is not nil
|
|
||||||
# - nilnil # checks that there is no simultaneous return of nil error and an invalid value
|
|
||||||
# - noctx # finds sending http request without context.Context
|
|
||||||
# - nolintlint # reports ill-formed or insufficient nolint directives
|
|
||||||
# - nonamedreturns # reports all named returns
|
|
||||||
# - nosprintfhostport # checks for misuse of Sprintf to construct a host with port in a URL
|
|
||||||
# - perfsprint # checks that fmt.Sprintf can be replaced with a faster alternative
|
|
||||||
# - predeclared # finds code that shadows one of Go's predeclared identifiers
|
|
||||||
# - promlinter # checks Prometheus metrics naming via promlint
|
|
||||||
# - protogetter # reports direct reads from proto message fields when getters should be used
|
|
||||||
# - reassign # checks that package variables are not reassigned
|
|
||||||
# - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint
|
|
||||||
# - rowserrcheck # checks whether Err of rows is checked successfully
|
|
||||||
# - sloglint # ensure consistent code style when using log/slog
|
|
||||||
# - spancheck # checks for mistakes with OpenTelemetry/Census spans
|
|
||||||
# - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed
|
|
||||||
# - stylecheck # is a replacement for golint
|
|
||||||
# - tenv # detects using os.Setenv instead of t.Setenv since Go1.17
|
|
||||||
# - testableexamples # checks if examples are testable (have an expected output)
|
|
||||||
# #- testifylint # checks usage of github.com/stretchr/testify
|
|
||||||
# - testpackage # makes you use a separate _test package
|
|
||||||
# - tparallel # detects inappropriate usage of t.Parallel() method in your Go test codes
|
|
||||||
# - unconvert # removes unnecessary type conversions
|
|
||||||
# - unparam # reports unused function parameters
|
|
||||||
# - usestdlibvars # detects the possibility to use variables/constants from the Go standard library
|
|
||||||
# - wastedassign # finds wasted assignment statements
|
|
||||||
# - whitespace # detects leading and trailing whitespace
|
|
||||||
|
|
||||||
# ## you may want to enable
|
|
||||||
# #- decorder # checks declaration order and count of types, constants, variables and functions
|
|
||||||
# #- exhaustruct # [highly recommend to enable] checks if all structure fields are initialized
|
|
||||||
# #- gci # controls golang package import order and makes it always deterministic
|
|
||||||
# #- ginkgolinter # [if you use ginkgo/gomega] enforces standards of using ginkgo and gomega
|
|
||||||
# #- godox # detects FIXME, TODO and other comment keywords
|
|
||||||
# #- goheader # checks is file header matches to pattern
|
|
||||||
# #- inamedparam # [great idea, but too strict, need to ignore a lot of cases by default] reports interfaces with unnamed method parameters
|
|
||||||
# #- interfacebloat # checks the number of methods inside an interface
|
|
||||||
# #- ireturn # accept interfaces, return concrete types
|
|
||||||
# #- prealloc # [premature optimization, but can be used in some cases] finds slice declarations that could potentially be preallocated
|
|
||||||
# #- tagalign # checks that struct tags are well aligned
|
|
||||||
# #- varnamelen # [great idea, but too many false positives] checks that the length of a variable's name matches its scope
|
|
||||||
# #- wrapcheck # checks that errors returned from external packages are wrapped
|
|
||||||
# #- zerologlint # detects the wrong usage of zerolog that a user forgets to dispatch zerolog.Event
|
|
||||||
|
|
||||||
# ## disabled
|
|
||||||
# #- containedctx # detects struct contained context.Context field
|
|
||||||
# #- contextcheck # [too many false positives] checks the function whether use a non-inherited context
|
|
||||||
# #- copyloopvar # [not necessary from Go 1.22] detects places where loop variables are copied
|
|
||||||
# #- depguard # [replaced by gomodguard] checks if package imports are in a list of acceptable packages
|
|
||||||
# #- dogsled # checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
|
|
||||||
# #- dupword # [useless without config] checks for duplicate words in the source code
|
|
||||||
# #- err113 # [too strict] checks the errors handling expressions
|
|
||||||
# #- errchkjson # [don't see profit + I'm against of omitting errors like in the first example https://github.com/breml/errchkjson] checks types passed to the json encoding functions. Reports unsupported types and optionally reports occasions, where the check for the returned error can be omitted
|
|
||||||
# #- execinquery # [deprecated] checks query string in Query function which reads your Go src files and warning it finds
|
|
||||||
# #- exportloopref # [not necessary from Go 1.22] checks for pointers to enclosing loop variables
|
|
||||||
# #- forcetypeassert # [replaced by errcheck] finds forced type assertions
|
|
||||||
# #- gofmt # [replaced by goimports] checks whether code was gofmt-ed
|
|
||||||
# #- gofumpt # [replaced by goimports, gofumports is not available yet] checks whether code was gofumpt-ed
|
|
||||||
# #- gosmopolitan # reports certain i18n/l10n anti-patterns in your Go codebase
|
|
||||||
# #- grouper # analyzes expression groups
|
|
||||||
# #- importas # enforces consistent import aliases
|
|
||||||
# #- maintidx # measures the maintainability index of each function
|
|
||||||
# #- misspell # [useless] finds commonly misspelled English words in comments
|
|
||||||
# #- nlreturn # [too strict and mostly code is not more readable] checks for a new line before return and branch statements to increase code clarity
|
|
||||||
# #- paralleltest # [too many false positives] detects missing usage of t.Parallel() method in your Go test
|
|
||||||
# #- tagliatelle # checks the struct tags
|
|
||||||
# #- thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers
|
|
||||||
# #- wsl # [too strict and mostly code is not more readable] whitespace linter forces you to use empty lines
|
|
||||||
|
|
||||||
# issues:
|
|
||||||
# # Maximum count of issues with the same text.
|
|
||||||
# # Set to 0 to disable.
|
|
||||||
# # Default: 3
|
|
||||||
# max-same-issues: 50
|
|
||||||
|
|
||||||
# exclude-rules:
|
|
||||||
# - source: "(noinspection|TODO)"
|
|
||||||
# linters: [godot]
|
|
||||||
# - source: "//noinspection"
|
|
||||||
# linters: [gocritic]
|
|
||||||
# - path: "example\\.go"
|
|
||||||
# linters:
|
|
||||||
# - lll
|
|
||||||
# - path: "_test\\.go"
|
|
||||||
# linters:
|
|
||||||
# - bodyclose
|
|
||||||
# - dupl
|
|
||||||
# - funlen
|
|
||||||
# - goconst
|
|
||||||
# - gosec
|
|
||||||
# - noctx
|
|
||||||
# - wrapcheck
|
|
||||||
# - lll
|
|
||||||
# - testpackage
|
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
FROM golang:1.23-alpine AS builder
|
|
||||||
|
|
||||||
# Install tools build
|
|
||||||
RUN apk add --no-cache git curl bash build-base
|
|
||||||
|
|
||||||
WORKDIR /lti-api
|
|
||||||
|
|
||||||
# Cache dependencies
|
|
||||||
COPY go.mod go.sum ./
|
|
||||||
RUN go mod download
|
|
||||||
|
|
||||||
# Copy source code
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Build binary dari entrypoint (cmd/api/main.go)
|
|
||||||
RUN CGO_ENABLED=0 GOOS=linux go build -o app ./cmd/api
|
|
||||||
|
|
||||||
FROM alpine:3.20
|
|
||||||
|
|
||||||
# Install tools
|
|
||||||
RUN apk add --no-cache curl
|
|
||||||
|
|
||||||
WORKDIR /lti-api
|
|
||||||
|
|
||||||
# Copy binary hasil build
|
|
||||||
COPY --from=builder /lti-api/app .
|
|
||||||
|
|
||||||
# Copy file env example
|
|
||||||
COPY --from=builder /lti-api/.env.example .env
|
|
||||||
|
|
||||||
EXPOSE 8080
|
|
||||||
|
|
||||||
CMD ["./app"]
|
|
||||||
@@ -5,7 +5,7 @@ export
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# --- Konfigurasi umum ---
|
# --- Konfigurasi umum ---
|
||||||
COMPOSE ?= docker compose -f docker-compose.dev.yml
|
COMPOSE ?= docker compose -f docker-compose.local.yml
|
||||||
NETWORK ?= lti-api_go-network
|
NETWORK ?= lti-api_go-network
|
||||||
MIGRATE_IMAGE ?= migrate/migrate
|
MIGRATE_IMAGE ?= migrate/migrate
|
||||||
MIGRATIONS_DIR := $(PWD)/internal/database/migrations
|
MIGRATIONS_DIR := $(PWD)/internal/database/migrations
|
||||||
@@ -31,7 +31,7 @@ WAIT_DB := docker run --rm --network $(NETWORK) postgres:alpine \
|
|||||||
db-up wait-db \
|
db-up wait-db \
|
||||||
migration-% migrate-up migrate-down migrate-fresh \
|
migration-% migrate-up migrate-down migrate-fresh \
|
||||||
seed \
|
seed \
|
||||||
docker-dev docker-prod docker-down docker-nuke docker-cache psql
|
docker-local docker-down docker-nuke docker-cache psql
|
||||||
|
|
||||||
# --- Go workflow ---
|
# --- Go workflow ---
|
||||||
start:
|
start:
|
||||||
@@ -90,12 +90,9 @@ seed: db-up wait-db
|
|||||||
@$(COMPOSE) run --rm app go run cmd/seed/main.go
|
@$(COMPOSE) run --rm app go run cmd/seed/main.go
|
||||||
|
|
||||||
# --- Docker orchestration convenience ---
|
# --- Docker orchestration convenience ---
|
||||||
docker-dev:
|
docker-local:
|
||||||
@$(COMPOSE) up --build -d
|
@$(COMPOSE) up --build -d
|
||||||
|
|
||||||
docker-prod:
|
|
||||||
@docker compose -f docker-compose.prod.yml up --build -d
|
|
||||||
|
|
||||||
docker-down:
|
docker-down:
|
||||||
@$(COMPOSE) down --remove-orphans
|
@$(COMPOSE) down --remove-orphans
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Lumbung Telur Indonesia ERP API (lti-api)
|
# Lumbung Telur Indonesia ERP API (lti-api)
|
||||||
|
|
||||||
Lumbung Telur Indonesia RESTful API, built with **Go, Fiber, GORM** and **PostgreSQL**.
|
RESTful API for **Lumbung Telur Indonesia ERP**, built with **Go, Fiber, GORM** and **PostgreSQL**.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ Lumbung Telur Indonesia RESTful API, built with **Go, Fiber, GORM** and **Postgr
|
|||||||
- **Fiber middleware** — Rate limiting, CORS, recovery, logger
|
- **Fiber middleware** — Rate limiting, CORS, recovery, logger
|
||||||
- **Air** — Hot reload for development
|
- **Air** — Hot reload for development
|
||||||
- **Docker + Docker Compose** — Containerization
|
- **Docker + Docker Compose** — Containerization
|
||||||
|
- **golang-migrate** — Database migration tool
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ cp .env.example .env
|
|||||||
Run initial docker.
|
Run initial docker.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make docker-dev
|
make docker-local
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Migrate Database
|
### 4. Migrate Database
|
||||||
@@ -105,8 +106,8 @@ internal/
|
|||||||
|
|
||||||
## ✨ Author
|
## ✨ Author
|
||||||
|
|
||||||
IT Development PT Mitra Berlian Unggas
|
IT Development PT Mitra Berlian Unggas Group
|
||||||
|
|
||||||
## 📃 License
|
## 📃 License
|
||||||
|
|
||||||
Free to use --change here
|
This project is private. All rights reserved.
|
||||||
|
|||||||
+20
-7
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -43,11 +44,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setupRedis() *redis.Client {
|
func setupRedis() *redis.Client {
|
||||||
redisURL := os.Getenv("REDIS_URL")
|
opt, err := redis.ParseURL(config.RedisURL)
|
||||||
if redisURL == "" {
|
|
||||||
redisURL = "redis://redis:6379/0"
|
|
||||||
}
|
|
||||||
opt, err := redis.ParseURL(redisURL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.Log.Fatalf("Redis URL parse error: %v", err)
|
utils.Log.Fatalf("Redis URL parse error: %v", err)
|
||||||
}
|
}
|
||||||
@@ -55,7 +52,7 @@ func setupRedis() *redis.Client {
|
|||||||
if err := rdb.Ping(context.Background()).Err(); err != nil {
|
if err := rdb.Ping(context.Background()).Err(); err != nil {
|
||||||
utils.Log.Fatalf("Redis ping failed: %v", err)
|
utils.Log.Fatalf("Redis ping failed: %v", err)
|
||||||
}
|
}
|
||||||
utils.Log.Infof("Redis connected: %s", redisURL)
|
utils.Log.Infof("Redis connected: %s", config.RedisURL)
|
||||||
return rdb
|
return rdb
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,6 +67,22 @@ func setupFiberApp() *fiber.App {
|
|||||||
app.Use(cors.New())
|
app.Use(cors.New())
|
||||||
app.Use(middleware.RecoverConfig())
|
app.Use(middleware.RecoverConfig())
|
||||||
|
|
||||||
|
origins := "*"
|
||||||
|
if len(config.CORSAllowOrigins) > 0 {
|
||||||
|
origins = strings.Join(config.CORSAllowOrigins, ",")
|
||||||
|
}
|
||||||
|
if config.CORSAllowCredentials && (origins == "" || origins == "*") {
|
||||||
|
origins = "http://localhost:3000"
|
||||||
|
}
|
||||||
|
app.Use(cors.New(cors.Config{
|
||||||
|
AllowOrigins: origins,
|
||||||
|
AllowMethods: strings.Join(config.CORSAllowMethods, ","),
|
||||||
|
AllowHeaders: strings.Join(config.CORSAllowHeaders, ","),
|
||||||
|
ExposeHeaders: strings.Join(config.CORSExposeHeaders, ","),
|
||||||
|
AllowCredentials: config.CORSAllowCredentials,
|
||||||
|
MaxAge: config.CORSMaxAge,
|
||||||
|
}))
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +99,7 @@ func setupRoutes(app *fiber.App, db *gorm.DB, rdb *redis.Client) {
|
|||||||
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"service": "api",
|
"service": "api",
|
||||||
"version": os.Getenv("VERSION"),
|
"version": config.Version,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,11 @@ services:
|
|||||||
- ./internal/database/init:/docker-entrypoint-initdb.d
|
- ./internal/database/init:/docker-entrypoint-initdb.d
|
||||||
networks: [go-network]
|
networks: [go-network]
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-db_lti_erp}"]
|
test:
|
||||||
|
[
|
||||||
|
"CMD-SHELL",
|
||||||
|
"pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-db_lti_erp}",
|
||||||
|
]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 5
|
retries: 5
|
||||||
@@ -29,29 +33,16 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
networks: [go-network]
|
networks: [go-network]
|
||||||
|
|
||||||
mailhog:
|
|
||||||
image: mailhog/mailhog:latest
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "1025:1025" # SMTP
|
|
||||||
- "8025:8025" # Web UI
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "wget -qO- http://localhost:8025/ || exit 1"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 3s
|
|
||||||
retries: 5
|
|
||||||
networks: [go-network]
|
|
||||||
|
|
||||||
app:
|
app:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.dev
|
dockerfile: Dockerfile.local
|
||||||
image: cosmtrek/air:v1.52.3
|
image: cosmtrek/air:v1.52.3
|
||||||
working_dir: /lti-api
|
working_dir: /lti-api
|
||||||
volumes:
|
volumes:
|
||||||
- .:/lti-api
|
- .:/lti-api
|
||||||
- ./internal/config/jwtRS256.key:/run/keys/jwtRS256.key:ro
|
- ./internal/config/jwtRS256.key:/run/keys/jwtRS256.key
|
||||||
- ./internal/config/jwtRS256.key.pub:/run/keys/jwtRS256.key.pub:ro
|
- ./internal/config/jwtRS256.key.pub:/run/keys/jwtRS256.key.pub
|
||||||
command: air -c .air.toml
|
command: air -c .air.toml
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
@@ -62,8 +53,6 @@ services:
|
|||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
||||||
DB_NAME: ${DB_NAME:-db_lti_erp}
|
DB_NAME: ${DB_NAME:-db_lti_erp}
|
||||||
REDIS_URL: ${REDIS_URL:-redis://redis:6379/0}
|
REDIS_URL: ${REDIS_URL:-redis://redis:6379/0}
|
||||||
SMTP_HOST: ${SMTP_HOST:-mailhog}
|
|
||||||
SMTP_PORT: ${SMTP_PORT:-1025}
|
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT:-8080}:8080"
|
- "${APP_PORT:-8080}:8080"
|
||||||
depends_on:
|
depends_on:
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
services:
|
|
||||||
postgresdb:
|
|
||||||
image: postgres:alpine
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "${DB_PORT:-5432}:5432"
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: ${DB_USER:-postgres}
|
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
|
|
||||||
POSTGRES_DB: ${DB_NAME:-db_lti_erp}
|
|
||||||
volumes:
|
|
||||||
- dbdata:/var/lib/postgresql/data
|
|
||||||
- ./internal/database/init:/docker-entrypoint-initdb.d
|
|
||||||
networks: [go-network]
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-db_lti_erp}"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.prod
|
|
||||||
image: lti-api-app
|
|
||||||
working_dir: /lti-api
|
|
||||||
command: ./app # asumsi Dockerfile.prod menghasilkan binary bernama "app"
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
|
||||||
DB_HOST: postgresdb
|
|
||||||
DB_PORT: 5432
|
|
||||||
DB_USER: ${DB_USER:-postgres}
|
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
|
||||||
DB_NAME: ${DB_NAME:-db_lti_erp}
|
|
||||||
ports:
|
|
||||||
- "${APP_PORT:-8080}:8080"
|
|
||||||
depends_on:
|
|
||||||
postgresdb:
|
|
||||||
condition: service_healthy
|
|
||||||
restart: on-failure
|
|
||||||
networks: [go-network]
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
dbdata:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
go-network:
|
|
||||||
name: lti-api_go-network
|
|
||||||
driver: bridge
|
|
||||||
@@ -12,13 +12,11 @@ require (
|
|||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/viper v1.19.0
|
github.com/spf13/viper v1.19.0
|
||||||
golang.org/x/crypto v0.33.0
|
golang.org/x/crypto v0.33.0
|
||||||
golang.org/x/oauth2 v0.22.0
|
|
||||||
gorm.io/driver/postgres v1.5.9
|
gorm.io/driver/postgres v1.5.9
|
||||||
gorm.io/gorm v1.25.11
|
gorm.io/gorm v1.25.11
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
|
||||||
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
|
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
|
||||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||||
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
github.com/bytedance/sonic/loader v0.2.0 // indirect
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
|
||||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
|
||||||
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
|
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
|
||||||
github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
|
github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
|
||||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||||
@@ -160,8 +158,6 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
|
||||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
|||||||
+70
-62
@@ -1,7 +1,8 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||||
|
|
||||||
@@ -9,32 +10,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
IsProd bool
|
IsProd bool
|
||||||
AppHost string
|
AppHost string
|
||||||
Version string
|
Version string
|
||||||
LogLevel string
|
LogLevel string
|
||||||
AppPort int
|
AppPort int
|
||||||
DBHost string
|
DBHost string
|
||||||
DBUser string
|
DBUser string
|
||||||
DBPassword string
|
DBPassword string
|
||||||
DBName string
|
DBName string
|
||||||
DBPort int
|
DBPort int
|
||||||
JWTSecret string
|
JWTSecret string
|
||||||
JWTAccessExp int
|
JWTAccessExp int
|
||||||
JWTRefreshExp int
|
JWTRefreshExp int
|
||||||
JWTResetPasswordExp int
|
JWTResetPasswordExp int
|
||||||
JWTVerifyEmailExp int
|
JWTVerifyEmailExp int
|
||||||
PostgresDSN string
|
RedisURL string
|
||||||
RedisURL string
|
CORSAllowOrigins []string
|
||||||
Issuer string
|
CORSAllowMethods []string
|
||||||
SMTPHost string
|
CORSAllowHeaders []string
|
||||||
SMTPPort int
|
CORSExposeHeaders []string
|
||||||
SMTPUsername string
|
CORSAllowCredentials bool
|
||||||
SMTPPassword string
|
CORSMaxAge int
|
||||||
EmailFrom string
|
|
||||||
GoogleClientID string
|
|
||||||
GoogleClientSecret string
|
|
||||||
RedirectURL string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -42,16 +39,8 @@ func init() {
|
|||||||
|
|
||||||
// server configuration
|
// server configuration
|
||||||
IsProd = viper.GetString("APP_ENV") == "prod"
|
IsProd = viper.GetString("APP_ENV") == "prod"
|
||||||
// AppHost = viper.GetString("APP_HOST")
|
|
||||||
// AppPort = viper.GetInt("APP_PORT")
|
|
||||||
AppHost = viper.GetString("APP_HOST")
|
AppHost = viper.GetString("APP_HOST")
|
||||||
if AppHost == "" {
|
|
||||||
AppHost = "0.0.0.0"
|
|
||||||
}
|
|
||||||
AppPort = viper.GetInt("APP_PORT")
|
AppPort = viper.GetInt("APP_PORT")
|
||||||
if AppPort == 0 {
|
|
||||||
AppPort = 8080
|
|
||||||
}
|
|
||||||
Version = viper.GetString("VERSION")
|
Version = viper.GetString("VERSION")
|
||||||
LogLevel = viper.GetString("LOG_LEVEL")
|
LogLevel = viper.GetString("LOG_LEVEL")
|
||||||
|
|
||||||
@@ -61,13 +50,6 @@ func init() {
|
|||||||
DBPassword = viper.GetString("DB_PASSWORD")
|
DBPassword = viper.GetString("DB_PASSWORD")
|
||||||
DBName = viper.GetString("DB_NAME")
|
DBName = viper.GetString("DB_NAME")
|
||||||
DBPort = viper.GetInt("DB_PORT")
|
DBPort = viper.GetInt("DB_PORT")
|
||||||
PostgresDSN = viper.GetString("POSTGRES_DSN")
|
|
||||||
if PostgresDSN == "" {
|
|
||||||
PostgresDSN = fmt.Sprintf(
|
|
||||||
"postgres://%s:%s@%s:%d/%s?sslmode=disable",
|
|
||||||
DBUser, DBPassword, DBHost, DBPort, DBName,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// jwt configuration
|
// jwt configuration
|
||||||
JWTSecret = viper.GetString("JWT_SECRET")
|
JWTSecret = viper.GetString("JWT_SECRET")
|
||||||
@@ -76,27 +58,16 @@ func init() {
|
|||||||
JWTResetPasswordExp = viper.GetInt("JWT_RESET_PASSWORD_EXP_MINUTES")
|
JWTResetPasswordExp = viper.GetInt("JWT_RESET_PASSWORD_EXP_MINUTES")
|
||||||
JWTVerifyEmailExp = viper.GetInt("JWT_VERIFY_EMAIL_EXP_MINUTES")
|
JWTVerifyEmailExp = viper.GetInt("JWT_VERIFY_EMAIL_EXP_MINUTES")
|
||||||
|
|
||||||
// Redis / OIDC
|
//Cors
|
||||||
RedisURL = viper.GetString("REDIS_URL")
|
CORSAllowOrigins = parseList("CORS_ALLOW_ORIGINS")
|
||||||
if RedisURL == "" {
|
CORSAllowMethods = parseListWithDefault("CORS_ALLOW_METHODS", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
|
||||||
RedisURL = "redis://redis:6379/0"
|
CORSAllowHeaders = parseListWithDefault("CORS_ALLOW_HEADERS", "Content-Type,Authorization,X-Requested-With")
|
||||||
}
|
CORSExposeHeaders = parseList("CORS_EXPOSE_HEADERS")
|
||||||
Issuer = viper.GetString("ISSUER")
|
CORSAllowCredentials = viper.GetBool("CORS_ALLOW_CREDENTIALS")
|
||||||
if Issuer == "" {
|
CORSMaxAge = viper.GetInt("CORS_MAX_AGE")
|
||||||
// fallback ke SSO_ISSUER jika kamu sudah pakai itu sebelumnya
|
|
||||||
Issuer = viper.GetString("SSO_ISSUER")
|
|
||||||
}
|
|
||||||
// SMTP configuration
|
|
||||||
SMTPHost = viper.GetString("SMTP_HOST")
|
|
||||||
SMTPPort = viper.GetInt("SMTP_PORT")
|
|
||||||
SMTPUsername = viper.GetString("SMTP_USERNAME")
|
|
||||||
SMTPPassword = viper.GetString("SMTP_PASSWORD")
|
|
||||||
EmailFrom = viper.GetString("EMAIL_FROM")
|
|
||||||
|
|
||||||
// oauth2 configuration
|
// Redis
|
||||||
GoogleClientID = viper.GetString("GOOGLE_CLIENT_ID")
|
RedisURL = viper.GetString("REDIS_URL")
|
||||||
GoogleClientSecret = viper.GetString("GOOGLE_CLIENT_SECRET")
|
|
||||||
RedirectURL = viper.GetString("REDIRECT_URL")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadConfig() {
|
func loadConfig() {
|
||||||
@@ -109,3 +80,40 @@ func loadConfig() {
|
|||||||
utils.Log.Warn("No .env file found, using environment variables only")
|
utils.Log.Warn("No .env file found, using environment variables only")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseList(key string) []string {
|
||||||
|
raw := strings.TrimSpace(viper.GetString(key))
|
||||||
|
if raw == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(raw, "[") {
|
||||||
|
var arr []string
|
||||||
|
if json.Unmarshal([]byte(raw), &arr) == nil {
|
||||||
|
for i := range arr {
|
||||||
|
arr[i] = strings.TrimSpace(arr[i])
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parts := strings.Split(raw, ",")
|
||||||
|
out := make([]string, 0, len(parts))
|
||||||
|
for _, p := range parts {
|
||||||
|
p = strings.TrimSpace(p)
|
||||||
|
if p != "" {
|
||||||
|
out = append(out, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseListWithDefault(key, def string) []string {
|
||||||
|
if v := parseList(key); len(v) > 0 {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
// fallback ke default CSV
|
||||||
|
parts := strings.Split(def, ",")
|
||||||
|
for i := range parts {
|
||||||
|
parts[i] = strings.TrimSpace(parts[i])
|
||||||
|
}
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArf9cLsf3m4TituVqDwvM
|
||||||
|
yaUwQ0rzDfOcmF/N+rHvgMMv1yyR4FcozoGk1NFfL/4jDIVm9FLUS68foPDo0iu5
|
||||||
|
shNY0pwSsps9lcyWxQVhUVJzh489S53hU799PiDrUPBxYTcpy3EO/jX0HOZJs5dl
|
||||||
|
N/4C54LYrVdXyleG82NLNjcMnNGr3VGc6zE7B3YYd9/daPyr+QBpeUL5BIzUZbeu
|
||||||
|
sI0NMIxucaqxMKWF62CDWTrwfSSoFOubI9FZ9tkkWro01wVFK35GseQCsDtEmJ9v
|
||||||
|
kb81LvfM2AcPLr+g1kN8dVeZLNNQTMrmxaWXFiwwEgayJ8q01pHfgAxg42ariKEK
|
||||||
|
fX9kFx/3Rs80qsXhQNEkoCOwQBRNwrRxRzNfVkvuE0aRVoO6PVFE1gDOLUV2fJJs
|
||||||
|
QUpAWMzZ/+e/N+1gKMtbaCbz2dLqnA6KkdMdHe79dMFVGx2ZnRFbyALzM3S5XgNV
|
||||||
|
QtVvTri2PW/6ZH41T6MpLUANzuwaIEys1Az+8VLxOgBugb63xoORB2JDsebxEfsS
|
||||||
|
HBllECnBJVuBndkJRSnbqGjCKq4sl2xXo83nZ+2eNmZO/vkTxREl8aVp3DgaHWxp
|
||||||
|
OQIlZwbP9lsruTqSnQfH3/hLemrOhSh/hXfFguw3oOQjfeFwJBD8u7vGOl2vBi3C
|
||||||
|
hvb8hFdjzoUXAJLxWPl5+E0CAwEAAQ==
|
||||||
|
-----END PUBLIC KEY-----
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package config
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/oauth2"
|
|
||||||
"golang.org/x/oauth2/google"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
GoogleLoginConfig oauth2.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
var AppConfig Config
|
|
||||||
|
|
||||||
func GoogleConfig() oauth2.Config {
|
|
||||||
AppConfig.GoogleLoginConfig = oauth2.Config{
|
|
||||||
RedirectURL: RedirectURL,
|
|
||||||
ClientID: GoogleClientID,
|
|
||||||
ClientSecret: GoogleClientSecret,
|
|
||||||
Scopes: []string{
|
|
||||||
"https://www.googleapis.com/auth/userinfo.email",
|
|
||||||
"https://www.googleapis.com/auth/userinfo.profile",
|
|
||||||
},
|
|
||||||
Endpoint: google.Endpoint,
|
|
||||||
}
|
|
||||||
|
|
||||||
return AppConfig.GoogleLoginConfig
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
DROP TABLE IF EXISTS users;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
-- Users
|
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
|
||||||
id BIGSERIAL PRIMARY KEY,
|
|
||||||
name VARCHAR,
|
|
||||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
||||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
||||||
deleted_at TIMESTAMPTZ
|
|
||||||
);
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
DROP TABLE IF EXISTS fcr_standards;
|
||||||
|
DROP INDEX IF EXISTS products_sku_unique;
|
||||||
|
DROP TABLE IF EXISTS products;
|
||||||
|
DROP TABLE IF EXISTS flags;
|
||||||
|
DROP INDEX IF EXISTS customers_email_unique;
|
||||||
|
DROP TABLE IF EXISTS customers;
|
||||||
|
DROP INDEX IF EXISTS product_categories_code_unique;
|
||||||
|
DROP TABLE IF EXISTS product_categories;
|
||||||
|
DROP TABLE IF EXISTS nonstocks;
|
||||||
|
DROP TABLE IF EXISTS banks;
|
||||||
|
DROP TABLE IF EXISTS warehouses;
|
||||||
|
DROP TABLE IF EXISTS kandangs;
|
||||||
|
DROP TABLE IF EXISTS locations;
|
||||||
|
DROP TABLE IF EXISTS areas;
|
||||||
|
DROP TABLE IF EXISTS uom;
|
||||||
|
DROP TABLE IF EXISTS suppliers;
|
||||||
|
DROP TABLE IF EXISTS fcr;
|
||||||
|
DROP TABLE IF EXISTS projects;
|
||||||
|
DROP INDEX IF EXISTS users_id_user_unique;
|
||||||
|
DROP INDEX IF EXISTS users_email_unique;
|
||||||
|
DROP TABLE IF EXISTS users;
|
||||||
@@ -0,0 +1,204 @@
|
|||||||
|
-- USERS
|
||||||
|
CREATE TABLE users (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
id_user BIGINT NOT NULL,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
email VARCHAR NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX users_id_user_unique ON users (id_user) WHERE deleted_at IS NULL;
|
||||||
|
CREATE UNIQUE INDEX users_email_unique ON users (email) WHERE deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- FLAGS
|
||||||
|
CREATE TABLE flags (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
flagable_id BIGINT NOT NULL,
|
||||||
|
flagable_type VARCHAR(50) NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ
|
||||||
|
);
|
||||||
|
|
||||||
|
-- PRODUCT CATEGORIES
|
||||||
|
CREATE TABLE product_categories (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
code VARCHAR(3) NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX product_categories_code_unique ON product_categories (code) WHERE deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- UOM
|
||||||
|
CREATE TABLE uom (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- PRODUCTS
|
||||||
|
CREATE TABLE products (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
brand VARCHAR NOT NULL,
|
||||||
|
sku VARCHAR(100),
|
||||||
|
uom_id BIGINT NOT NULL REFERENCES uom(id),
|
||||||
|
product_category_id BIGINT NOT NULL REFERENCES product_categories(id),
|
||||||
|
product_price NUMERIC(15,2) NOT NULL,
|
||||||
|
selling_price NUMERIC(15,2),
|
||||||
|
tax NUMERIC(15,2),
|
||||||
|
expiry_period INT,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX products_sku_unique ON products (sku) WHERE deleted_at IS NULL;
|
||||||
|
|
||||||
|
-- BANKS
|
||||||
|
CREATE TABLE banks (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
alias VARCHAR(5) NOT NULL,
|
||||||
|
owner VARCHAR,
|
||||||
|
account_number VARCHAR(50) NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- AREAS
|
||||||
|
CREATE TABLE areas (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- LOCATIONS
|
||||||
|
CREATE TABLE locations (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
area_id BIGINT NOT NULL REFERENCES areas(id),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- KANDANG
|
||||||
|
CREATE TABLE kandangs (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(191) NOT NULL,
|
||||||
|
location_id BIGINT NOT NULL REFERENCES locations(id),
|
||||||
|
pic_id BIGINT NOT NULL REFERENCES users(id),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- WAREHOUSES
|
||||||
|
CREATE TABLE warehouses (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
type VARCHAR(50) NOT NULL,
|
||||||
|
location_id BIGINT NOT NULL REFERENCES locations(id),
|
||||||
|
kandang_id BIGINT REFERENCES kandangs(id),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CUSTOMERS
|
||||||
|
CREATE TABLE customers (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
pic_id BIGINT REFERENCES users(id),
|
||||||
|
type VARCHAR(50) NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
phone VARCHAR(20) NOT NULL,
|
||||||
|
email VARCHAR NOT NULL,
|
||||||
|
account_number VARCHAR(50) NOT NULL,
|
||||||
|
balance NUMERIC(15,2) DEFAULT 0,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- NONSTOCK
|
||||||
|
CREATE TABLE nonstocks (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
uom_id BIGINT NOT NULL REFERENCES uom(id),
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- FCR
|
||||||
|
CREATE TABLE fcr (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE fcr_standards (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
fcr_id BIGINT NOT NULL REFERENCES fcr(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
weight NUMERIC(15,2) NOT NULL,
|
||||||
|
fcr_number NUMERIC(15,2) NOT NULL,
|
||||||
|
mortality NUMERIC(15,2) NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ
|
||||||
|
);
|
||||||
|
|
||||||
|
-- SUPPLIERS
|
||||||
|
CREATE TABLE suppliers (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR NOT NULL,
|
||||||
|
alias VARCHAR(5) NOT NULL,
|
||||||
|
pic VARCHAR NOT NULL,
|
||||||
|
type VARCHAR(50) NOT NULL,
|
||||||
|
hatchery VARCHAR,
|
||||||
|
phone VARCHAR(20) NOT NULL,
|
||||||
|
email VARCHAR NOT NULL,
|
||||||
|
address TEXT NOT NULL,
|
||||||
|
npwp VARCHAR(50),
|
||||||
|
account_number VARCHAR(50),
|
||||||
|
balance NUMERIC(15,2) DEFAULT 0,
|
||||||
|
due_date INT NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- PROJECTS
|
||||||
|
CREATE TABLE projects (
|
||||||
|
id BIGSERIAL PRIMARY KEY,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||||
|
deleted_at TIMESTAMPTZ,
|
||||||
|
created_by BIGINT NOT NULL REFERENCES users(id)
|
||||||
|
);
|
||||||
@@ -10,17 +10,13 @@ import (
|
|||||||
|
|
||||||
func Run(db *gorm.DB) error {
|
func Run(db *gorm.DB) error {
|
||||||
return db.Transaction(func(tx *gorm.DB) error {
|
return db.Transaction(func(tx *gorm.DB) error {
|
||||||
// pw, err := secure.Hash("asdasdasd", nil)
|
|
||||||
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// ===== Users (user) =====
|
// ===== Users (user) =====
|
||||||
user := mUser.User{
|
user := mUser.User{
|
||||||
Name: "Super Admin",
|
Email: "admin@mbugroup.id",
|
||||||
|
IdUser: 1,
|
||||||
|
Name: "Super Admin",
|
||||||
}
|
}
|
||||||
if err := tx.Where("email = ?", user.Id).FirstOrCreate(&user).Error; err != nil {
|
if err := tx.Where("email = ?", user.Email).FirstOrCreate(&user).Error; err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,15 @@ import (
|
|||||||
|
|
||||||
// === DTO Structs ===
|
// === DTO Structs ===
|
||||||
|
|
||||||
|
type UserBaseDTO struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
IdUser int64 `json:"id_user"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
type UserListDTO struct {
|
type UserListDTO struct {
|
||||||
Id uint `json:"id"`
|
UserBaseDTO
|
||||||
Name string `json:"name"`
|
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -21,13 +27,21 @@ type UserDetailDTO struct {
|
|||||||
|
|
||||||
// === Mapper Functions ===
|
// === Mapper Functions ===
|
||||||
|
|
||||||
func ToUserListDTO(m model.User) UserListDTO {
|
func ToUserBaseDTO(m model.User) UserBaseDTO {
|
||||||
return UserListDTO{
|
return UserBaseDTO{
|
||||||
Id: m.Id,
|
Id: m.Id,
|
||||||
Name: m.Name,
|
Name: m.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToUserListDTO(m model.User) UserListDTO {
|
||||||
|
return UserListDTO{
|
||||||
|
UserBaseDTO: ToUserBaseDTO(m),
|
||||||
|
CreatedAt: m.CreatedAt,
|
||||||
|
UpdatedAt: m.UpdatedAt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ToUserListDTOs(m []model.User) []UserListDTO {
|
func ToUserListDTOs(m []model.User) []UserListDTO {
|
||||||
result := make([]UserListDTO, len(m))
|
result := make([]UserListDTO, len(m))
|
||||||
for i, r := range m {
|
for i, r := range m {
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Id uint `gorm:"primaryKey"`
|
Id uint `gorm:"primaryKey"`
|
||||||
|
IdUser int64 `gorm:"uniqueIndex"`
|
||||||
|
Email string `gorm:"uniqueIndex"`
|
||||||
Name string `gorm:"not null"`
|
Name string `gorm:"not null"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package repository
|
|||||||
import (
|
import (
|
||||||
model "gitlab.com/mbugroup/lti-api.git/internal/modules/users/models"
|
model "gitlab.com/mbugroup/lti-api.git/internal/modules/users/models"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/repository"
|
"gitlab.com/mbugroup/lti-api.git/internal/repository"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func (s *userService) CreateOne(c *fiber.Ctx, req *validation.Create) (*model.Us
|
|||||||
}
|
}
|
||||||
|
|
||||||
createBody := &model.User{
|
createBody := &model.User{
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.Repository.CreateOne(c.Context(), createBody, nil); err != nil {
|
if err := s.Repository.CreateOne(c.Context(), createBody, nil); err != nil {
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ func Routes(app *fiber.App, db *gorm.DB) {
|
|||||||
validate := validation.Validator()
|
validate := validation.Validator()
|
||||||
api := app.Group("/api")
|
api := app.Group("/api")
|
||||||
|
|
||||||
// masterRoute.Routes(api, db)
|
|
||||||
|
|
||||||
// root modules di sini
|
// root modules di sini
|
||||||
allModules := []modules.Module{
|
allModules := []modules.Module{
|
||||||
users.UserModule{},
|
users.UserModule{},
|
||||||
|
|||||||
@@ -8,9 +8,13 @@ import (
|
|||||||
|
|
||||||
// === DTO Structs ===
|
// === DTO Structs ===
|
||||||
|
|
||||||
type {{Pascal .Entity}}ListDTO struct {
|
type {{Pascal .Entity}}BaseDTO struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type {{Pascal .Entity}}ListDTO struct {
|
||||||
|
{{Pascal .Entity}}BaseDTO
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -21,10 +25,18 @@ type {{Pascal .Entity}}DetailDTO struct {
|
|||||||
|
|
||||||
// === Mapper Functions ===
|
// === Mapper Functions ===
|
||||||
|
|
||||||
|
func To{{Pascal .Entity}}BaseDTO(m model.{{Pascal .Entity}}) {{Pascal .Entity}}BaseDTO {
|
||||||
|
return {{Pascal .Entity}}BaseDTO{
|
||||||
|
Id: m.Id,
|
||||||
|
Name: m.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func To{{Pascal .Entity}}ListDTO(m model.{{Pascal .Entity}}) {{Pascal .Entity}}ListDTO {
|
func To{{Pascal .Entity}}ListDTO(m model.{{Pascal .Entity}}) {{Pascal .Entity}}ListDTO {
|
||||||
return {{Pascal .Entity}}ListDTO{
|
return {{Pascal .Entity}}ListDTO{
|
||||||
Id: m.Id,
|
{{Pascal .Entity}}BaseDTO: To{{Pascal .Entity}}BaseDTO(m),
|
||||||
Name: m.Name,
|
CreatedAt: m.CreatedAt,
|
||||||
|
UpdatedAt: m.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user