mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 05:21:57 +00:00
fix: adjust docker and any file for starting project
This commit is contained in:
+10
-15
@@ -1,5 +1,6 @@
|
||||
# server configuration
|
||||
# Env value : prod || dev
|
||||
VERSION=0.0.1
|
||||
APP_ENV=dev
|
||||
APP_HOST=0.0.0.0
|
||||
APP_PORT=8080
|
||||
@@ -13,25 +14,19 @@ DB_NAME=db_lti_erp
|
||||
DB_PORT=5432
|
||||
|
||||
# JWT
|
||||
# JWT secret key
|
||||
JWT_SECRET=changeme
|
||||
# Number of minutes after which an access token expires
|
||||
JWT_ACCESS_EXP_MINUTES=30
|
||||
# Number of days after which a refresh token expires
|
||||
JWT_REFRESH_EXP_DAYS=30
|
||||
# Number of minutes after which a reset password token expires
|
||||
JWT_RESET_PASSWORD_EXP_MINUTES=10
|
||||
# Number of minutes after which a verify email token expires
|
||||
JWT_VERIFY_EMAIL_EXP_MINUTES=10
|
||||
|
||||
# SMTP configuration options for the email service
|
||||
SMTP_HOST=email-server
|
||||
SMTP_PORT=587
|
||||
SMTP_USERNAME=email-server-username
|
||||
SMTP_PASSWORD=changeme
|
||||
EMAIL_FROM=support@yourapp.com
|
||||
# CORS
|
||||
CORS_ALLOW_ORIGINS=changeme
|
||||
CORS_ALLOW_METHODS=GET,POST,PUT,PATCH,DELETE,OPTIONS
|
||||
CORS_ALLOW_HEADERS=Authorization,Content-Type,X-Requested-With
|
||||
CORS_EXPOSE_HEADERS=Link,Location
|
||||
CORS_ALLOW_CREDENTIALS=true
|
||||
CORS_MAX_AGE=600
|
||||
|
||||
# OAuth2 configuration
|
||||
GOOGLE_CLIENT_ID=yourapps.googleusercontent.com
|
||||
GOOGLE_CLIENT_SECRET=changeme
|
||||
REDIRECT_URL=http://localhost:3000/v1/auth/google-callback
|
||||
# Redis
|
||||
REDIS_URL=redis://redis:6379/0
|
||||
|
||||
@@ -10,6 +10,9 @@ bin/
|
||||
*.exe
|
||||
*.out
|
||||
|
||||
# Go build cache
|
||||
.gocache/
|
||||
|
||||
# Logs & reports
|
||||
*.log
|
||||
*.txt
|
||||
|
||||
+200
-343
@@ -1,346 +1,203 @@
|
||||
# ## Config for golangci-lint v1.60.1
|
||||
## Config for golangci-lint v2 schema
|
||||
version: "2"
|
||||
|
||||
# run:
|
||||
# # Timeout for analysis, e.g. 30s, 5m.
|
||||
# # Default: 1m
|
||||
# timeout: 3m
|
||||
run:
|
||||
timeout: 3m
|
||||
|
||||
# # This file contains only configs which differ from defaults.
|
||||
# # All possible options can be found here https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
|
||||
# linters-settings:
|
||||
# cyclop:
|
||||
# # The maximal code complexity to report.
|
||||
# # Default: 10
|
||||
# max-complexity: 30
|
||||
# # The maximal average package complexity.
|
||||
# # If it's higher than 0.0 (float) the check is enabled
|
||||
# # Default: 0.0
|
||||
# package-average: 10.0
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
## enabled by default
|
||||
- errcheck
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- unused
|
||||
## disabled by default
|
||||
- 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:
|
||||
# # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
|
||||
# # 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
|
||||
issues:
|
||||
max-same-issues: 50
|
||||
|
||||
@@ -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
|
||||
|
||||
# --- Konfigurasi umum ---
|
||||
COMPOSE ?= docker compose -f docker-compose.dev.yml
|
||||
COMPOSE ?= docker compose -f docker-compose.local.yml
|
||||
NETWORK ?= lti-api_go-network
|
||||
MIGRATE_IMAGE ?= migrate/migrate
|
||||
MIGRATIONS_DIR := $(PWD)/internal/database/migrations
|
||||
@@ -31,7 +31,7 @@ WAIT_DB := docker run --rm --network $(NETWORK) postgres:alpine \
|
||||
db-up wait-db \
|
||||
migration-% migrate-up migrate-down migrate-fresh \
|
||||
seed \
|
||||
docker-dev docker-prod docker-down docker-nuke docker-cache psql
|
||||
docker-local docker-down docker-nuke docker-cache psql
|
||||
|
||||
# --- Go workflow ---
|
||||
start:
|
||||
@@ -90,12 +90,9 @@ seed: db-up wait-db
|
||||
@$(COMPOSE) run --rm app go run cmd/seed/main.go
|
||||
|
||||
# --- Docker orchestration convenience ---
|
||||
docker-dev:
|
||||
docker-local:
|
||||
@$(COMPOSE) up --build -d
|
||||
|
||||
docker-prod:
|
||||
@docker compose -f docker-compose.prod.yml up --build -d
|
||||
|
||||
docker-down:
|
||||
@$(COMPOSE) down --remove-orphans
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 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
|
||||
- **Air** — Hot reload for development
|
||||
- **Docker + Docker Compose** — Containerization
|
||||
- **golang-migrate** — Database migration tool
|
||||
|
||||
---
|
||||
|
||||
@@ -46,7 +47,7 @@ cp .env.example .env
|
||||
Run initial docker.
|
||||
|
||||
```bash
|
||||
make docker-dev
|
||||
make docker-local
|
||||
```
|
||||
|
||||
### 4. Migrate Database
|
||||
@@ -105,8 +106,8 @@ internal/
|
||||
|
||||
## ✨ Author
|
||||
|
||||
IT Development PT Mitra Berlian Unggas
|
||||
IT Development PT Mitra Berlian Unggas Group
|
||||
|
||||
## 📃 License
|
||||
|
||||
Free to use --change here
|
||||
This project is private. All rights reserved.
|
||||
|
||||
+20
-7
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -43,11 +44,7 @@ func main() {
|
||||
}
|
||||
|
||||
func setupRedis() *redis.Client {
|
||||
redisURL := os.Getenv("REDIS_URL")
|
||||
if redisURL == "" {
|
||||
redisURL = "redis://redis:6379/0"
|
||||
}
|
||||
opt, err := redis.ParseURL(redisURL)
|
||||
opt, err := redis.ParseURL(config.RedisURL)
|
||||
if err != nil {
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -70,6 +67,22 @@ func setupFiberApp() *fiber.App {
|
||||
app.Use(cors.New())
|
||||
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
|
||||
}
|
||||
|
||||
@@ -86,7 +99,7 @@ func setupRoutes(app *fiber.App, db *gorm.DB, rdb *redis.Client) {
|
||||
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
||||
"status": "ok",
|
||||
"service": "api",
|
||||
"version": os.Getenv("VERSION"),
|
||||
"version": config.Version,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -13,7 +13,11 @@ services:
|
||||
- ./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}"]
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-db_lti_erp}",
|
||||
]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
@@ -29,29 +33,16 @@ services:
|
||||
retries: 10
|
||||
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:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
dockerfile: Dockerfile.local
|
||||
image: cosmtrek/air:v1.52.3
|
||||
working_dir: /lti-api
|
||||
volumes:
|
||||
- .:/lti-api
|
||||
- ./internal/config/jwtRS256.key:/run/keys/jwtRS256.key:ro
|
||||
- ./internal/config/jwtRS256.key.pub:/run/keys/jwtRS256.key.pub:ro
|
||||
- ./internal/config/jwtRS256.key:/run/keys/jwtRS256.key
|
||||
- ./internal/config/jwtRS256.key.pub:/run/keys/jwtRS256.key.pub
|
||||
command: air -c .air.toml
|
||||
env_file:
|
||||
- .env
|
||||
@@ -62,8 +53,6 @@ services:
|
||||
DB_PASSWORD: ${DB_PASSWORD:-postgres}
|
||||
DB_NAME: ${DB_NAME:-db_lti_erp}
|
||||
REDIS_URL: ${REDIS_URL:-redis://redis:6379/0}
|
||||
SMTP_HOST: ${SMTP_HOST:-mailhog}
|
||||
SMTP_PORT: ${SMTP_PORT:-1025}
|
||||
ports:
|
||||
- "${APP_PORT:-8080}:8080"
|
||||
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/spf13/viper v1.19.0
|
||||
golang.org/x/crypto v0.33.0
|
||||
golang.org/x/oauth2 v0.22.0
|
||||
gorm.io/driver/postgres v1.5.9
|
||||
gorm.io/gorm v1.25.11
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
|
||||
github.com/andybalholm/brotli v1.1.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/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
|
||||
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.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
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-20220722155255-886fb9371eb4/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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
|
||||
@@ -9,32 +10,28 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
IsProd bool
|
||||
AppHost string
|
||||
Version string
|
||||
LogLevel string
|
||||
AppPort int
|
||||
DBHost string
|
||||
DBUser string
|
||||
DBPassword string
|
||||
DBName string
|
||||
DBPort int
|
||||
JWTSecret string
|
||||
JWTAccessExp int
|
||||
JWTRefreshExp int
|
||||
JWTResetPasswordExp int
|
||||
JWTVerifyEmailExp int
|
||||
PostgresDSN string
|
||||
RedisURL string
|
||||
Issuer string
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
SMTPUsername string
|
||||
SMTPPassword string
|
||||
EmailFrom string
|
||||
GoogleClientID string
|
||||
GoogleClientSecret string
|
||||
RedirectURL string
|
||||
IsProd bool
|
||||
AppHost string
|
||||
Version string
|
||||
LogLevel string
|
||||
AppPort int
|
||||
DBHost string
|
||||
DBUser string
|
||||
DBPassword string
|
||||
DBName string
|
||||
DBPort int
|
||||
JWTSecret string
|
||||
JWTAccessExp int
|
||||
JWTRefreshExp int
|
||||
JWTResetPasswordExp int
|
||||
JWTVerifyEmailExp int
|
||||
RedisURL string
|
||||
CORSAllowOrigins []string
|
||||
CORSAllowMethods []string
|
||||
CORSAllowHeaders []string
|
||||
CORSExposeHeaders []string
|
||||
CORSAllowCredentials bool
|
||||
CORSMaxAge int
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -42,16 +39,8 @@ func init() {
|
||||
|
||||
// server configuration
|
||||
IsProd = viper.GetString("APP_ENV") == "prod"
|
||||
// AppHost = viper.GetString("APP_HOST")
|
||||
// AppPort = viper.GetInt("APP_PORT")
|
||||
AppHost = viper.GetString("APP_HOST")
|
||||
if AppHost == "" {
|
||||
AppHost = "0.0.0.0"
|
||||
}
|
||||
AppPort = viper.GetInt("APP_PORT")
|
||||
if AppPort == 0 {
|
||||
AppPort = 8080
|
||||
}
|
||||
Version = viper.GetString("VERSION")
|
||||
LogLevel = viper.GetString("LOG_LEVEL")
|
||||
|
||||
@@ -61,13 +50,6 @@ func init() {
|
||||
DBPassword = viper.GetString("DB_PASSWORD")
|
||||
DBName = viper.GetString("DB_NAME")
|
||||
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
|
||||
JWTSecret = viper.GetString("JWT_SECRET")
|
||||
@@ -76,27 +58,16 @@ func init() {
|
||||
JWTResetPasswordExp = viper.GetInt("JWT_RESET_PASSWORD_EXP_MINUTES")
|
||||
JWTVerifyEmailExp = viper.GetInt("JWT_VERIFY_EMAIL_EXP_MINUTES")
|
||||
|
||||
// Redis / OIDC
|
||||
RedisURL = viper.GetString("REDIS_URL")
|
||||
if RedisURL == "" {
|
||||
RedisURL = "redis://redis:6379/0"
|
||||
}
|
||||
Issuer = viper.GetString("ISSUER")
|
||||
if Issuer == "" {
|
||||
// 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")
|
||||
//Cors
|
||||
CORSAllowOrigins = parseList("CORS_ALLOW_ORIGINS")
|
||||
CORSAllowMethods = parseListWithDefault("CORS_ALLOW_METHODS", "GET,POST,PUT,PATCH,DELETE,OPTIONS")
|
||||
CORSAllowHeaders = parseListWithDefault("CORS_ALLOW_HEADERS", "Content-Type,Authorization,X-Requested-With")
|
||||
CORSExposeHeaders = parseList("CORS_EXPOSE_HEADERS")
|
||||
CORSAllowCredentials = viper.GetBool("CORS_ALLOW_CREDENTIALS")
|
||||
CORSMaxAge = viper.GetInt("CORS_MAX_AGE")
|
||||
|
||||
// oauth2 configuration
|
||||
GoogleClientID = viper.GetString("GOOGLE_CLIENT_ID")
|
||||
GoogleClientSecret = viper.GetString("GOOGLE_CLIENT_SECRET")
|
||||
RedirectURL = viper.GetString("REDIRECT_URL")
|
||||
// Redis
|
||||
RedisURL = viper.GetString("REDIS_URL")
|
||||
}
|
||||
|
||||
func loadConfig() {
|
||||
@@ -109,3 +80,40 @@ func loadConfig() {
|
||||
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 {
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
// pw, err := secure.Hash("asdasdasd", nil)
|
||||
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// ===== Users (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
|
||||
}
|
||||
|
||||
|
||||
@@ -8,9 +8,15 @@ import (
|
||||
|
||||
// === 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 {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
UserBaseDTO
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
@@ -21,13 +27,21 @@ type UserDetailDTO struct {
|
||||
|
||||
// === Mapper Functions ===
|
||||
|
||||
func ToUserListDTO(m model.User) UserListDTO {
|
||||
return UserListDTO{
|
||||
func ToUserBaseDTO(m model.User) UserBaseDTO {
|
||||
return UserBaseDTO{
|
||||
Id: m.Id,
|
||||
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 {
|
||||
result := make([]UserListDTO, len(m))
|
||||
for i, r := range m {
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
|
||||
type User struct {
|
||||
Id uint `gorm:"primaryKey"`
|
||||
IdUser int64 `gorm:"uniqueIndex"`
|
||||
Email string `gorm:"uniqueIndex"`
|
||||
Name string `gorm:"not null"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
|
||||
@@ -3,7 +3,6 @@ package repository
|
||||
import (
|
||||
model "gitlab.com/mbugroup/lti-api.git/internal/modules/users/models"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/repository"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ func (s *userService) CreateOne(c *fiber.Ctx, req *validation.Create) (*model.Us
|
||||
}
|
||||
|
||||
createBody := &model.User{
|
||||
Name: req.Name,
|
||||
Name: req.Name,
|
||||
}
|
||||
|
||||
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()
|
||||
api := app.Group("/api")
|
||||
|
||||
// masterRoute.Routes(api, db)
|
||||
|
||||
// root modules di sini
|
||||
allModules := []modules.Module{
|
||||
users.UserModule{},
|
||||
|
||||
@@ -8,9 +8,13 @@ import (
|
||||
|
||||
// === DTO Structs ===
|
||||
|
||||
type {{Pascal .Entity}}ListDTO struct {
|
||||
type {{Pascal .Entity}}BaseDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type {{Pascal .Entity}}ListDTO struct {
|
||||
{{Pascal .Entity}}BaseDTO
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
@@ -21,10 +25,18 @@ type {{Pascal .Entity}}DetailDTO struct {
|
||||
|
||||
// === 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 {
|
||||
return {{Pascal .Entity}}ListDTO{
|
||||
Id: m.Id,
|
||||
Name: m.Name,
|
||||
{{Pascal .Entity}}BaseDTO: To{{Pascal .Entity}}BaseDTO(m),
|
||||
CreatedAt: m.CreatedAt,
|
||||
UpdatedAt: m.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user