add tysc handlers to kontor-gin
This commit is contained in:
@@ -10,7 +10,7 @@ RUN go mod download
|
|||||||
# Copy the source code
|
# Copy the source code
|
||||||
COPY . .
|
COPY . .
|
||||||
# Build the Go application (strip debug info for smaller size)
|
# Build the Go application (strip debug info for smaller size)
|
||||||
RUN go build -trimpath -ldflags="-s -w" -o kontor-gin cmd/kontor-gin/main.go
|
RUN go build -trimpath -ldflags="-s -w" -o kontor cmd/kontor/main.go
|
||||||
|
|
||||||
# ---------- Stage 2: Final ----------
|
# ---------- Stage 2: Final ----------
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
@@ -19,9 +19,10 @@ WORKDIR /app
|
|||||||
# Install runtime dependencies you actually need
|
# Install runtime dependencies you actually need
|
||||||
RUN apk add --no-cache ca-certificates tzdata curl
|
RUN apk add --no-cache ca-certificates tzdata curl
|
||||||
# Copy the binary and set ownership
|
# Copy the binary and set ownership
|
||||||
COPY --from=builder /app/kontor-gin /app/kontor-gin
|
COPY --from=builder /app/kontor /app/kontor
|
||||||
COPY --from=builder /app/templates /app/templates
|
#COPY --from=builder /app/kontor-gin /app/kontor-gin
|
||||||
COPY --from=builder /app/assets /app/assets
|
#COPY --from=builder /app/templates /app/templates
|
||||||
ENV GIN_MODE=release
|
#COPY --from=builder /app/assets /app/assets
|
||||||
|
#ENV GIN_MODE=release
|
||||||
# Set the entrypoint command
|
# Set the entrypoint command
|
||||||
ENTRYPOINT ["/app/kontor-gin"]
|
ENTRYPOINT ["/app/kontor"]
|
||||||
|
|||||||
@@ -1,93 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
// "kontor-api-gin/pkg/handler"
|
|
||||||
|
|
||||||
"kontor-api-gin/internal/globals"
|
|
||||||
"kontor-api-gin/internal/schema"
|
|
||||||
"kontor-api-gin/pkg/middleware"
|
|
||||||
"kontor-api-gin/pkg/routes"
|
|
||||||
"log"
|
|
||||||
"log/slog"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/sessions"
|
|
||||||
"github.com/gin-contrib/sessions/cookie"
|
|
||||||
gin_slog "github.com/gin-contrib/slog"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
slog.Info("Kontor started")
|
|
||||||
|
|
||||||
viper.SetDefault("db.host", "localhost")
|
|
||||||
viper.SetDefault("db.port", 5432)
|
|
||||||
viper.SetDefault("db.name", "kontor")
|
|
||||||
viper.SetDefault("db.user", "kontor")
|
|
||||||
viper.SetDefault("db.password", "kontor")
|
|
||||||
viper.SetDefault("port", 8550)
|
|
||||||
viper.SetDefault("token_hour_lifespan", 1)
|
|
||||||
viper.SetDefault("api_secret", "secret")
|
|
||||||
|
|
||||||
if err := globals.InitConfig(); err != nil {
|
|
||||||
slog.Info("Failed to initialize config", "error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set Gin mode based on environment
|
|
||||||
// Production mode disables debug output
|
|
||||||
if os.Getenv("GIN_MODE") == "release" {
|
|
||||||
gin.SetMode(gin.ReleaseMode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Connect to database
|
|
||||||
schema.Connect()
|
|
||||||
|
|
||||||
// Run migrations
|
|
||||||
schema.RunMigrations()
|
|
||||||
|
|
||||||
// Create Gin router with default middleware
|
|
||||||
// Default includes Logger and Recovery middleware
|
|
||||||
// router := gin.Default()
|
|
||||||
// Create a new router without default mmiddleware
|
|
||||||
router := gin.New()
|
|
||||||
// Add recovery middleware
|
|
||||||
router.Use(gin.Recovery())
|
|
||||||
router.Use(gin_slog.SetLogger(
|
|
||||||
gin_slog.WithSkipPath([]string{"/health", "/public/style/main.css"}),
|
|
||||||
gin_slog.WithDefaultLevel(slog.LevelInfo),
|
|
||||||
gin_slog.WithClientErrorLevel(slog.LevelInfo),
|
|
||||||
gin_slog.WithServerErrorLevel(slog.LevelInfo),
|
|
||||||
))
|
|
||||||
|
|
||||||
router.LoadHTMLGlob("templates/**/*.html")
|
|
||||||
router.Static("/public", "./assets")
|
|
||||||
|
|
||||||
router.Use(sessions.Sessions("session", cookie.NewStore(globals.Secret)))
|
|
||||||
|
|
||||||
// Setup api routes
|
|
||||||
api := routes.SetupApiRoutes(router)
|
|
||||||
api.Use(middleware.CorsMiddleware)
|
|
||||||
api.Use(middleware.JwtRequired)
|
|
||||||
routes.SetupMediaRoutes(api)
|
|
||||||
routes.SetupComicRoutes(api)
|
|
||||||
|
|
||||||
// Setup Webapp routes
|
|
||||||
routes.AuthRoutes(router)
|
|
||||||
routes.ComicRoutes(router)
|
|
||||||
routes.MediaRoutes(router)
|
|
||||||
routes.PublicRoutes(router)
|
|
||||||
|
|
||||||
// Start server
|
|
||||||
port := os.Getenv("PORT")
|
|
||||||
if port == "" {
|
|
||||||
port = "8550"
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Info("Server starting", "port", port)
|
|
||||||
if err := router.Run(":" + port); err != nil {
|
|
||||||
log.Fatal("Failed to start server:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Info("Kontor finished")
|
|
||||||
}
|
|
||||||
@@ -4,11 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"kontor-api-gin/internal/config"
|
"kontor-api-gin/internal/config"
|
||||||
"kontor-api-gin/internal/globals"
|
|
||||||
"kontor-api-gin/internal/handlers"
|
"kontor-api-gin/internal/handlers"
|
||||||
"kontor-api-gin/internal/repository"
|
|
||||||
"kontor-api-gin/internal/router"
|
"kontor-api-gin/internal/router"
|
||||||
"kontor-api-gin/internal/service"
|
|
||||||
"log"
|
"log"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
@@ -25,7 +22,7 @@ import (
|
|||||||
func main() {
|
func main() {
|
||||||
slog.Info("Kontor started")
|
slog.Info("Kontor started")
|
||||||
|
|
||||||
if err := globals.InitConfig(); err != nil {
|
if err := config.InitConfig(); err != nil {
|
||||||
log.Fatalf("Failed to initialize config: %v", err)
|
log.Fatalf("Failed to initialize config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,11 +43,6 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
comicRepo := repository.NewComicRepository(db)
|
|
||||||
profileRepo := repository.NewProfileRepository(db)
|
|
||||||
comicService := service.NewComicService(comicRepo)
|
|
||||||
authService := service.NewAuthService(profileRepo, []byte(viper.GetString("api_secret")))
|
|
||||||
|
|
||||||
// Set Gin mode based on environment
|
// Set Gin mode based on environment
|
||||||
// Production mode disables debug output
|
// Production mode disables debug output
|
||||||
if viper.GetString("gin.mode") == "release" {
|
if viper.GetString("gin.mode") == "release" {
|
||||||
@@ -58,11 +50,12 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r := router.New(
|
r := router.New(
|
||||||
&handlers.ComicHandler{Service: comicService},
|
handlers.NewAdminHandler(db, []byte(viper.GetString("api_secret"))),
|
||||||
&handlers.AuthHandler{Service: authService},
|
handlers.NewComicsHandler(db),
|
||||||
[]byte(viper.GetString("api_secret")),
|
handlers.NewMediaHandler(db),
|
||||||
|
handlers.NewTyscHandler(db),
|
||||||
|
handlers.NewWebAppHandler(db, []byte(viper.GetString("api_secret"))),
|
||||||
)
|
)
|
||||||
// router.Use(sessions.Sessions("session", cookie.NewStore(globals.Secret)))
|
|
||||||
|
|
||||||
srv := &http.Server{
|
srv := &http.Server{
|
||||||
Addr: ":" + strconv.Itoa(viper.GetInt("port")),
|
Addr: ":" + strconv.Itoa(viper.GetInt("port")),
|
||||||
|
|||||||
+7
-3
@@ -4,9 +4,9 @@ go 1.26.8
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gin-contrib/cors v1.7.2
|
github.com/gin-contrib/cors v1.7.2
|
||||||
github.com/gin-contrib/sessions v1.0.2
|
github.com/gin-contrib/sessions v1.1.2
|
||||||
github.com/gin-contrib/slog v1.1.0
|
github.com/gin-contrib/slog v1.1.0
|
||||||
github.com/gin-gonic/gin v1.10.1
|
github.com/gin-gonic/gin v1.12.0
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/spf13/cobra v1.10.2
|
github.com/spf13/cobra v1.10.2
|
||||||
@@ -27,9 +27,10 @@ require (
|
|||||||
github.com/gin-contrib/sse v1.1.2 // indirect
|
github.com/gin-contrib/sse v1.1.2 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
github.com/go-playground/validator/v10 v10.30.3 // indirect
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.6 // indirect
|
github.com/goccy/go-json v0.10.6 // indirect
|
||||||
|
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||||
github.com/gorilla/context v1.1.2 // indirect
|
github.com/gorilla/context v1.1.2 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
github.com/gorilla/sessions v1.4.0 // indirect
|
github.com/gorilla/sessions v1.4.0 // indirect
|
||||||
@@ -47,6 +48,8 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
|
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
|
||||||
|
github.com/quic-go/qpack v0.6.0 // indirect
|
||||||
|
github.com/quic-go/quic-go v0.60.0 // indirect
|
||||||
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
github.com/sagikazarmark/locafero v0.12.0 // indirect
|
||||||
github.com/spf13/afero v1.15.0 // indirect
|
github.com/spf13/afero v1.15.0 // indirect
|
||||||
github.com/spf13/cast v1.10.0 // indirect
|
github.com/spf13/cast v1.10.0 // indirect
|
||||||
@@ -55,6 +58,7 @@ require (
|
|||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.3.2 // indirect
|
github.com/ugorji/go/codec v1.3.2 // indirect
|
||||||
|
go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect
|
||||||
go.yaml.in/yaml/v3 v3.0.5 // indirect
|
go.yaml.in/yaml/v3 v3.0.5 // indirect
|
||||||
golang.org/x/arch v0.31.0 // indirect
|
golang.org/x/arch v0.31.0 // indirect
|
||||||
golang.org/x/net v0.59.0 // indirect
|
golang.org/x/net v0.59.0 // indirect
|
||||||
|
|||||||
@@ -20,12 +20,16 @@ github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQ
|
|||||||
github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E=
|
github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E=
|
||||||
github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA=
|
github.com/gin-contrib/sessions v1.0.2 h1:UaIjUvTH1cMeOdj3in6dl+Xb6It8RiKRF9Z1anbUyCA=
|
||||||
github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs=
|
github.com/gin-contrib/sessions v1.0.2/go.mod h1:KxKxWqWP5LJVDCInulOl4WbLzK2KSPlLesfZ66wRvMs=
|
||||||
|
github.com/gin-contrib/sessions v1.1.2 h1:utWRqOHT/kbqxxqF/mtutV9wfGLi1+uu5YuvWUhj/Ow=
|
||||||
|
github.com/gin-contrib/sessions v1.1.2/go.mod h1:qRxYwA/TYJw0wv28oFzs4gY/8G8z69id862SNgX9Gmw=
|
||||||
github.com/gin-contrib/slog v1.1.0 h1:K9MVNrETT6r/C3u2Aheer/gxwVeVqrGL0hXlsmv3fm4=
|
github.com/gin-contrib/slog v1.1.0 h1:K9MVNrETT6r/C3u2Aheer/gxwVeVqrGL0hXlsmv3fm4=
|
||||||
github.com/gin-contrib/slog v1.1.0/go.mod h1:PvNXQVXcVOAaaiJR84LV1/xlQHIaXi9ygEXyBkmjdkY=
|
github.com/gin-contrib/slog v1.1.0/go.mod h1:PvNXQVXcVOAaaiJR84LV1/xlQHIaXi9ygEXyBkmjdkY=
|
||||||
github.com/gin-contrib/sse v1.1.2 h1:MU2fgl1RrdYTMcgJLtz2kJF+vPg3xrqaaKfUUU18tCo=
|
github.com/gin-contrib/sse v1.1.2 h1:MU2fgl1RrdYTMcgJLtz2kJF+vPg3xrqaaKfUUU18tCo=
|
||||||
github.com/gin-contrib/sse v1.1.2/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s=
|
github.com/gin-contrib/sse v1.1.2/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s=
|
||||||
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ=
|
||||||
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
|
||||||
|
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
|
||||||
|
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
@@ -34,10 +38,14 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
|
|||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8=
|
||||||
|
github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc=
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||||
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
|
||||||
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||||
|
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
|
||||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
@@ -89,6 +97,10 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
|
|||||||
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
|
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
|
||||||
github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||||
|
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||||
|
github.com/quic-go/quic-go v0.60.0 h1:xcQioE8OM66UQLeUMHltK1CCcOu3JbVB4JAQdDQSB+0=
|
||||||
|
github.com/quic-go/quic-go v0.60.0/go.mod h1:wpKpjmPpftl30sL6pFh7REVpjbcCVy4zt2vDyK1TuJk=
|
||||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
@@ -123,6 +135,9 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
|||||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||||
github.com/ugorji/go/codec v1.3.2 h1:zkEASHHyEClGeURfgNT9PJZVfAbs9oEX9QXggwWNJbc=
|
github.com/ugorji/go/codec v1.3.2 h1:zkEASHHyEClGeURfgNT9PJZVfAbs9oEX9QXggwWNJbc=
|
||||||
github.com/ugorji/go/codec v1.3.2/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
github.com/ugorji/go/codec v1.3.2/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||||
|
go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU=
|
||||||
|
go.mongodb.org/mongo-driver/v2 v2.8.0 h1:CxWDGQYY8QQwNjAl/aq2sfWakdnWZynnqJ9F4DhHbP8=
|
||||||
|
go.mongodb.org/mongo-driver/v2 v2.8.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||||
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
|
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
|
||||||
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
|
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@@ -26,7 +27,7 @@ var checkCmd = &cobra.Command{
|
|||||||
slog.Info("Verbosity level", "level", verbose)
|
slog.Info("Verbosity level", "level", verbose)
|
||||||
var login LoginResponse
|
var login LoginResponse
|
||||||
client := resty.New()
|
client := resty.New()
|
||||||
res, err := client.R().
|
_, err := client.R().
|
||||||
SetBody(Login{
|
SetBody(Login{
|
||||||
Email: "thomas.peetz@thpeetz.de",
|
Email: "thomas.peetz@thpeetz.de",
|
||||||
Password: "admin",
|
Password: "admin",
|
||||||
@@ -38,14 +39,23 @@ var checkCmd = &cobra.Command{
|
|||||||
slog.Info("Health", "error", err.Error())
|
slog.Info("Health", "error", err.Error())
|
||||||
}
|
}
|
||||||
slog.Info("health", "token", login.Token)
|
slog.Info("health", "token", login.Token)
|
||||||
res, err = client.R().
|
|
||||||
|
type ExportData struct {
|
||||||
|
Sport []models.SportDTO `json:"sport"`
|
||||||
|
Comic []models.ComicDTO `json:"comic"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var comics []models.ComicDTO
|
||||||
|
_, err = client.R().
|
||||||
SetAuthToken(login.Token).
|
SetAuthToken(login.Token).
|
||||||
SetHeader("Accept", "application/json").
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&comics).
|
||||||
Get("http://127.0.0.1:8550/api/v1/comics/comics")
|
Get("http://127.0.0.1:8550/api/v1/comics/comics")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
slog.Info("comics", "error", err.Error())
|
slog.Info("comics", "error", err.Error())
|
||||||
}
|
}
|
||||||
slog.Info("comics", "res", res)
|
// slog.Info("comics", "res", comics)
|
||||||
|
|
||||||
defer client.Close()
|
defer client.Close()
|
||||||
|
|
||||||
slog.Info("kontor.check_kontor.check_duplicate_links")
|
slog.Info("kontor.check_kontor.check_duplicate_links")
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"resty.dev/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var exportCmd = &cobra.Command{
|
var exportCmd = &cobra.Command{
|
||||||
@@ -14,6 +18,106 @@ var exportCmd = &cobra.Command{
|
|||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
slog.Info("export kontor")
|
slog.Info("export kontor")
|
||||||
slog.Info("Verbosity level", "level", verbose)
|
slog.Info("Verbosity level", "level", verbose)
|
||||||
|
var login LoginResponse
|
||||||
|
client := resty.New()
|
||||||
|
_, err := client.R().
|
||||||
|
SetBody(Login{
|
||||||
|
Email: "thomas.peetz@thpeetz.de",
|
||||||
|
Password: "admin",
|
||||||
|
}).
|
||||||
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&login).
|
||||||
|
Post("http://127.0.0.1:8550/api/login")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("Health", "error", err.Error())
|
||||||
|
}
|
||||||
|
slog.Info("health", "token", login.Token)
|
||||||
|
|
||||||
|
type ExportData struct {
|
||||||
|
Sport []models.SportDTO `json:"sport"`
|
||||||
|
Player []models.PlayerDTO `json:"player"`
|
||||||
|
Team []models.TeamDTO `json:"team"`
|
||||||
|
Position []models.PositionDTO `json:"field_position"`
|
||||||
|
Rooster []models.RoosterDTO `json:"rooster"`
|
||||||
|
Vendor []models.VendorDTO `json:"vendor"`
|
||||||
|
CardSet []models.CardSetDTO `json:"card_set"`
|
||||||
|
Card []models.CardDTO `json:"card"`
|
||||||
|
Comic []models.ComicDTO `json:"comic"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var sports []models.SportDTO
|
||||||
|
_, err = client.R().
|
||||||
|
SetAuthToken(login.Token).
|
||||||
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&sports).
|
||||||
|
Get("http://127.0.0.1:8550/api/v1/tysc/sports")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("sports", "error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var players []models.PlayerDTO
|
||||||
|
_, err = client.R().
|
||||||
|
SetAuthToken(login.Token).
|
||||||
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&players).
|
||||||
|
Get("http://127.0.0.1:8550/api/v1/tysc/players")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("players", "error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var teams []models.TeamDTO
|
||||||
|
_, err = client.R().
|
||||||
|
SetAuthToken(login.Token).
|
||||||
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&teams).
|
||||||
|
Get("http://127.0.0.1:8550/api/v1/tysc/teams")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("teams", "error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var positions []models.PositionDTO
|
||||||
|
_, err = client.R().
|
||||||
|
SetAuthToken(login.Token).
|
||||||
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&positions).
|
||||||
|
Get("http://127.0.0.1:8550/api/v1/tysc/positions")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("teams", "error", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var comics []models.ComicDTO
|
||||||
|
_, err = client.R().
|
||||||
|
SetAuthToken(login.Token).
|
||||||
|
SetHeader("Accept", "application/json").
|
||||||
|
SetResult(&comics).
|
||||||
|
Get("http://127.0.0.1:8550/api/v1/comics/comics")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("comics", "error", err.Error())
|
||||||
|
}
|
||||||
|
// slog.Info("comics", "res", comics)
|
||||||
|
|
||||||
|
data := ExportData{
|
||||||
|
Sport: sports,
|
||||||
|
Player: players,
|
||||||
|
Team: teams,
|
||||||
|
Position: positions,
|
||||||
|
Rooster: []models.RoosterDTO{},
|
||||||
|
Vendor: []models.VendorDTO{},
|
||||||
|
CardSet: []models.CardSetDTO{},
|
||||||
|
Card: []models.CardDTO{},
|
||||||
|
Comic: comics,
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
jsonData, err := json.MarshalIndent(data, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("JSON MarshalIndent failed", "Error:", err)
|
||||||
|
}
|
||||||
|
// Write bytes to file
|
||||||
|
err = os.WriteFile("data.json", jsonData, 0644)
|
||||||
|
if err != nil {
|
||||||
|
slog.Info("Error writing file:", "Error", err)
|
||||||
|
}
|
||||||
|
slog.Info("export kontor finished")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func InitConfig() error {
|
func InitConfig() error {
|
||||||
|
viper.SetDefault("db.host", "localhost")
|
||||||
|
viper.SetDefault("db.port", 5432)
|
||||||
|
viper.SetDefault("db.name", "kontor")
|
||||||
|
viper.SetDefault("db.user", "kontor")
|
||||||
|
viper.SetDefault("db.password", "kontor")
|
||||||
|
viper.SetDefault("port", 8550)
|
||||||
|
viper.SetDefault("gin.mode", "release")
|
||||||
|
|
||||||
viper.SetConfigName("kontor-gin")
|
viper.SetConfigName("kontor-gin")
|
||||||
viper.SetConfigType("yaml")
|
viper.SetConfigType("yaml")
|
||||||
viper.AddConfigPath(".")
|
viper.AddConfigPath(".")
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package globals
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log/slog"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitConfig() error {
|
|
||||||
viper.SetDefault("db.host", "localhost")
|
|
||||||
viper.SetDefault("db.port", 5432)
|
|
||||||
viper.SetDefault("db.name", "kontor")
|
|
||||||
viper.SetDefault("db.user", "kontor")
|
|
||||||
viper.SetDefault("db.password", "kontor")
|
|
||||||
viper.SetDefault("port", 8550)
|
|
||||||
viper.SetDefault("gin.mode", "release")
|
|
||||||
|
|
||||||
viper.SetConfigName("kontor-gin")
|
|
||||||
viper.SetConfigType("yaml")
|
|
||||||
viper.AddConfigPath(".")
|
|
||||||
viper.AddConfigPath("$HOME/.config")
|
|
||||||
viper.AddConfigPath("/etc/kontor")
|
|
||||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
|
||||||
viper.AutomaticEnv()
|
|
||||||
|
|
||||||
// Read the config file
|
|
||||||
if err := viper.ReadInConfig(); err != nil {
|
|
||||||
// Handle the case where config file is not found
|
|
||||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
|
||||||
slog.Info("No config file found, using defaults")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("error reading config file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Info("initConfig", "Using config file: ", viper.ConfigFileUsed())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,3 @@ var Secret = []byte("secret")
|
|||||||
const UserKey = "user"
|
const UserKey = "user"
|
||||||
|
|
||||||
const Version = "0.4.0"
|
const Version = "0.4.0"
|
||||||
|
|
||||||
const LoginUrl = "/login"
|
|
||||||
|
|
||||||
const LogoutUrl = "/auth/logout"
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AdminHandler struct {
|
||||||
|
AuthHandler *AuthHandler
|
||||||
|
PermissionHandler *PermissionHandler
|
||||||
|
Secret []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAdminHandler(db *gorm.DB, secret []byte) *AdminHandler {
|
||||||
|
adminHandler := &AdminHandler{
|
||||||
|
AuthHandler: &AuthHandler{Service: service.NewAuthService(repository.NewProfileRepository(db), secret)},
|
||||||
|
PermissionHandler: &PermissionHandler{Service: service.NewPermissionService(repository.NewPermissionRepository(db))},
|
||||||
|
Secret: secret,
|
||||||
|
}
|
||||||
|
return adminHandler
|
||||||
|
}
|
||||||
@@ -1,23 +1,128 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
"kontor-api-gin/internal/helpers"
|
"kontor-api-gin/internal/helpers"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
"kontor-api-gin/internal/service"
|
"kontor-api-gin/internal/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-contrib/slog"
|
"github.com/gin-contrib/slog"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthHandler struct {
|
type AuthHandler struct {
|
||||||
Service *service.AuthService
|
Service *service.AuthService
|
||||||
|
Secret []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (handler *AuthHandler) Login(c *gin.Context) {
|
func (handler *AuthHandler) Login(c *gin.Context) {
|
||||||
token, err := helpers.GenerateToken("bla")
|
var input models.LoginInput
|
||||||
|
|
||||||
|
if err := c.ShouldBindJSON(&input); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
proile_id, err := handler.Service.LoginCheck(input.Email, input.Password)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": "username or password is incorrect."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := helpers.GenerateToken(proile_id)
|
||||||
logger := slog.Get(c)
|
logger := slog.Get(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Info("Login", "GenerateToken error", err.Error())
|
logger.Info("Login", "GenerateToken error", err.Error())
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, gin.H{"token": token})
|
c.JSON(http.StatusOK, gin.H{"token": token})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (handler *AuthHandler) LoginPage(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
logger := slog.Get(c)
|
||||||
|
logger.Info("LoginPage", globals.UserKey, user)
|
||||||
|
if user != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "login", gin.H{
|
||||||
|
"title": "Kontor Gin",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "Please logout first",
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "login", gin.H{
|
||||||
|
"title": "Kontor Gin",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "",
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *AuthHandler) LoginPost(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
logger := slog.Get(c)
|
||||||
|
logger.Info("LoginPost", "user", user)
|
||||||
|
if user != nil {
|
||||||
|
c.HTML(http.StatusBadRequest, "login", gin.H{
|
||||||
|
"title": "Kontor Gin",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "Please logout first",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
username := c.PostForm("username")
|
||||||
|
password := c.PostForm("password")
|
||||||
|
|
||||||
|
if helpers.EmptyUserPass(username, password) {
|
||||||
|
c.HTML(http.StatusBadRequest, "login", gin.H{
|
||||||
|
"title": "Kontor Gin",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "Parameters can't be empty",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
proile_id, err := handler.Service.LoginCheck(username, password)
|
||||||
|
if err != nil {
|
||||||
|
c.HTML(http.StatusUnauthorized, "login", gin.H{
|
||||||
|
"title": "Kontor Gin",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "Incorrect username or password",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Set(globals.UserKey, proile_id)
|
||||||
|
if err := session.Save(); err != nil {
|
||||||
|
c.HTML(http.StatusInternalServerError, "login", gin.H{
|
||||||
|
"title": "Kontor Gin",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "Failed to save session",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Info("LoginPost: redirect to index")
|
||||||
|
c.Redirect(http.StatusMovedPermanently, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *AuthHandler) LogoutPage(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
logger := slog.Get(c)
|
||||||
|
logger.Info("LogoutPage", globals.UserKey, user)
|
||||||
|
if user == nil {
|
||||||
|
logger.Info("Invalid session token")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
session.Delete(globals.UserKey)
|
||||||
|
if err := session.Save(); err != nil {
|
||||||
|
logger.Info("Failed to save session", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Info("LogoutPage: redirect to index page")
|
||||||
|
c.Redirect(http.StatusMovedPermanently, "/")
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,37 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
"kontor-api-gin/internal/service"
|
"kontor-api-gin/internal/service"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ComicsHandler struct {
|
||||||
|
ComicHandler *ComicHandler
|
||||||
|
PublisherHandler *PublisherHandler
|
||||||
|
// ArtistHandler *ArtistHandler
|
||||||
|
// IssueHandler *IssueHandler
|
||||||
|
// WorktypeHandler *WorktypeHandler
|
||||||
|
// VolumeHandler *VolumeHandler
|
||||||
|
// StoryarcHandler *StoryarcHandler
|
||||||
|
// ComicworkHandler *ComicworkHandler
|
||||||
|
// IssueworkHandler *IssueworkHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewComicsHandler(db *gorm.DB) *ComicsHandler {
|
||||||
|
comicsHandler := &ComicsHandler{
|
||||||
|
ComicHandler: &ComicHandler{Service: service.NewComicService(repository.NewComicRepository(db))},
|
||||||
|
PublisherHandler: &PublisherHandler{Service: service.NewPublisherService(repository.NewPublisherRepository(db))},
|
||||||
|
}
|
||||||
|
return comicsHandler
|
||||||
|
}
|
||||||
|
|
||||||
type ComicHandler struct {
|
type ComicHandler struct {
|
||||||
Service *service.ComicService
|
Service *service.ComicService
|
||||||
}
|
}
|
||||||
@@ -17,5 +42,23 @@ func (handler *ComicHandler) List(c *gin.Context) {
|
|||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, comics)
|
dtos := models.ConvertComicsToDtos(comics)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *ComicHandler) ListPage(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
comics, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "comics", gin.H{
|
||||||
|
"title": "Kontor Comics",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "Comics...",
|
||||||
|
"comics": comics,
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,25 @@
|
|||||||
package controllers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"kontor-api-gin/pkg/globals"
|
"kontor-api-gin/internal/globals"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gin-contrib/sessions"
|
"github.com/gin-contrib/sessions"
|
||||||
"github.com/gin-contrib/slog"
|
"github.com/gin-contrib/slog"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func IndexGetHandler(c *gin.Context) {
|
func Health(c *gin.Context) {
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"ok": true,
|
||||||
|
"status": "healthy",
|
||||||
|
"version": globals.Version,
|
||||||
|
"time": time.Now().UTC().Format(time.RFC3339),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func Index(c *gin.Context) {
|
||||||
session := sessions.Default(c)
|
session := sessions.Default(c)
|
||||||
user := session.Get(globals.UserKey)
|
user := session.Get(globals.UserKey)
|
||||||
logger := slog.Get(c)
|
logger := slog.Get(c)
|
||||||
@@ -18,8 +28,7 @@ func IndexGetHandler(c *gin.Context) {
|
|||||||
"title": "Kontor Gin",
|
"title": "Kontor Gin",
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
"message": "This is an index page...",
|
"message": "This is an index page...",
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"logout": globals.LogoutUrl,
|
|
||||||
"user": user,
|
"user": user,
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaHandler struct {
|
||||||
|
MediaActorHandler *MediaActorHandler
|
||||||
|
MediaFileHandler *MediaFileHandler
|
||||||
|
MediaLoFiHandler *MediaLoFiHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaHandler(db *gorm.DB) *MediaHandler {
|
||||||
|
mediaHandler := &MediaHandler{
|
||||||
|
MediaActorHandler: &MediaActorHandler{Service: service.NewMediaActorService(repository.NewMediaActorRepository(db))},
|
||||||
|
MediaFileHandler: &MediaFileHandler{Service: service.NewMediaFileService(repository.NewMediaFileRepository(db))},
|
||||||
|
MediaLoFiHandler: &MediaLoFiHandler{Service: service.NewMediaLoFiService(repository.NewMediaLoFiRepository(db))},
|
||||||
|
}
|
||||||
|
return mediaHandler
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaActorHandler struct {
|
||||||
|
Service *service.MediaActorService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaActorHandler(db *gorm.DB) *MediaActorHandler {
|
||||||
|
mediaActorHandler := &MediaActorHandler{
|
||||||
|
Service: service.NewMediaActorService(repository.NewMediaActorRepository(db)),
|
||||||
|
}
|
||||||
|
return mediaActorHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *MediaActorHandler) List(c *gin.Context) {
|
||||||
|
lofis, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertMediaActorsToDtos(lofis)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *MediaActorHandler) ListPage(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
actors, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "mediaactors", gin.H{
|
||||||
|
"title": "Kontor MediaActors",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "MediaActors...",
|
||||||
|
"actors": actors,
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-contrib/slog"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaFileHandler struct {
|
||||||
|
Service *service.MediaFileService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaFileHandler(db *gorm.DB) *MediaFileHandler {
|
||||||
|
mediaFileHandler := &MediaFileHandler{
|
||||||
|
Service: service.NewMediaFileService(repository.NewMediaFileRepository(db)),
|
||||||
|
}
|
||||||
|
return mediaFileHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *MediaFileHandler) List(c *gin.Context) {
|
||||||
|
logger := slog.Get(c)
|
||||||
|
logger.Info("MediaFileHandler#List")
|
||||||
|
files, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertMediaFilesToDtos(files)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *MediaFileHandler) ListPage(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
files, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "mediafiles", gin.H{
|
||||||
|
"title": "Kontor MediaFiles",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "MediaFiles...",
|
||||||
|
"mediafiles": files,
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaLoFiHandler struct {
|
||||||
|
Service *service.MediaLoFiService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaLoFiHandler(db *gorm.DB) *MediaLoFiHandler {
|
||||||
|
mediaLoFiHandler := &MediaLoFiHandler{
|
||||||
|
Service: service.NewMediaLoFiService(repository.NewMediaLoFiRepository(db)),
|
||||||
|
}
|
||||||
|
return mediaLoFiHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *MediaLoFiHandler) List(c *gin.Context) {
|
||||||
|
lofis, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertMediaLoFisToDtos(lofis)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *MediaLoFiHandler) ListPage(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
lofis, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.HTML(http.StatusOK, "lofi", gin.H{
|
||||||
|
"title": "Kontor MediaFiles",
|
||||||
|
"version": "0.4.0",
|
||||||
|
"message": "MediaFiles...",
|
||||||
|
"lofis": lofis,
|
||||||
|
"user": user,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermissionHandler struct {
|
||||||
|
Service *service.PermissionService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *PermissionHandler) List(c *gin.Context) {
|
||||||
|
permissions, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, permissions)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlayerHandler struct {
|
||||||
|
Service *service.PlayerService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *PlayerHandler) List(c *gin.Context) {
|
||||||
|
players, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertPlayersToDtos(players)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *PlayerHandler) Get(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
player, err := handler.Service.Get(c.Request.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "player not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, player)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PositionHandler struct {
|
||||||
|
Service *service.PositionService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *PositionHandler) List(c *gin.Context) {
|
||||||
|
positions, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertPositionsToDtos(positions)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *PositionHandler) Get(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
position, err := handler.Service.Get(c.Request.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "position not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, position)
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PublisherHandler struct {
|
||||||
|
Service *service.PublisherService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *PublisherHandler) List(c *gin.Context) {
|
||||||
|
comics, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertPublishersToDtos(comics)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SportHandler struct {
|
||||||
|
Service *service.SportService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *SportHandler) List(c *gin.Context) {
|
||||||
|
sports, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertSportsToDtos(sports)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *SportHandler) Get(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
sport, err := handler.Service.Get(c.Request.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "sport not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, sport)
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TeamHandler struct {
|
||||||
|
Service *service.TeamService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *TeamHandler) List(c *gin.Context) {
|
||||||
|
teams, err := handler.Service.List(c.Request.Context())
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dtos := models.ConvertTeamsToDtos(teams)
|
||||||
|
c.JSON(http.StatusOK, dtos)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (handler *TeamHandler) Get(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
team, err := handler.Service.Get(c.Request.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusNotFound, gin.H{"error": "team not found"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, team)
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TyscHandler struct {
|
||||||
|
SportHandler *SportHandler
|
||||||
|
PlayerHandler *PlayerHandler
|
||||||
|
TeamHandler *TeamHandler
|
||||||
|
PositionHandler *PositionHandler
|
||||||
|
// RoosterHandler *RoosterHandler
|
||||||
|
// VendorHandler *VendorHandler
|
||||||
|
// CardSetHandler *CardSetHandler
|
||||||
|
// CardHandler *CardHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTyscHandler(db *gorm.DB) *TyscHandler {
|
||||||
|
handlerMap := &TyscHandler{
|
||||||
|
SportHandler: &SportHandler{Service: service.NewSportService(repository.NewSportRepository(db))},
|
||||||
|
PlayerHandler: &PlayerHandler{Service: service.NewPlayerService(repository.NewPlayerRepository(db))},
|
||||||
|
TeamHandler: &TeamHandler{Service: service.NewTeamService(repository.NewTeamRepository(db))},
|
||||||
|
PositionHandler: &PositionHandler{Service: service.NewPositionService(repository.NewPositionRepository(db))},
|
||||||
|
}
|
||||||
|
return handlerMap
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"kontor-api-gin/internal/service"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WebAppHandler struct {
|
||||||
|
AuthHandler *AuthHandler
|
||||||
|
ComicHandler *ComicHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWebAppHandler(db *gorm.DB, secret []byte) *WebAppHandler {
|
||||||
|
webapp := &WebAppHandler{
|
||||||
|
AuthHandler: &AuthHandler{Service: service.NewAuthService(repository.NewProfileRepository(db), secret)},
|
||||||
|
ComicHandler: &ComicHandler{Service: service.NewComicService(repository.NewComicRepository(db))},
|
||||||
|
}
|
||||||
|
return webapp
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
package helpers
|
package helpers
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
func CheckUserPass(username, password string) bool {
|
func CheckUserPass(username, password string) bool {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-contrib/slog"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func AuthRequired() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
session := sessions.Default(c)
|
||||||
|
user := session.Get(globals.UserKey)
|
||||||
|
logger := slog.Get(c)
|
||||||
|
logger.Info("AuthRequired", globals.UserKey, user)
|
||||||
|
if user == nil {
|
||||||
|
logger.Info("User not logged in")
|
||||||
|
c.Redirect(http.StatusMovedPermanently, "/login")
|
||||||
|
c.Abort()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,16 +1,23 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/slog"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RequestID() gin.HandlerFunc {
|
func RequestID(skipPaths []string) gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
logger := slog.Get(c)
|
||||||
id := c.GetHeader("X-Request-ID")
|
id := c.GetHeader("X-Request-ID")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
id = uuid.NewString()
|
id = uuid.NewString()
|
||||||
}
|
}
|
||||||
|
if len(skipPaths) > 0 && !slices.Contains(skipPaths, c.Request.URL.Path) {
|
||||||
|
logger.Info("RequestID", "id", id)
|
||||||
|
}
|
||||||
c.Set("request_id", id)
|
c.Set("request_id", id)
|
||||||
c.Writer.Header().Set("X-Request-ID", id)
|
c.Writer.Header().Set("X-Request-ID", id)
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Artist struct {
|
type Artist struct {
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
@@ -18,4 +18,5 @@ func (artist *Artist) TableName() string {
|
|||||||
|
|
||||||
type CreateArtistDTO struct {
|
type CreateArtistDTO struct {
|
||||||
Name string `json:"name" binding:"required"`
|
Name string `json:"name" binding:"required"`
|
||||||
|
WebLink string `json:"weblink" binding:"required"`
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Assignment struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
ProfileID *string `gorm:"column:profile_id" json:"profile_id"`
|
||||||
|
Profile *Profile `gorm:"foreignKey:ProfileID" json:"profile"`
|
||||||
|
PermissionID *string `gorm:"column:permission_id" json:"permission_id"`
|
||||||
|
Permission *Profile `gorm:"foreignKey:PermissionID" json:"permission"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (assignment *Assignment) TableName() string {
|
||||||
|
return "assignment"
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssignmentDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
ProfileID *string `json:"profile_id" binding:"required"`
|
||||||
|
PermissionID *string `json:"permission_id" binding:"required"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Card struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
CardNumber int `gorm:"column:card_number" json:"card_number"`
|
||||||
|
Year int `gorm:"column:year" json:"year"`
|
||||||
|
CardSetID string `gorm:"column:card_set_id" json:"card_set_id"`
|
||||||
|
CardSet CardSet `gorm:"foreignKey:CardSetID" json:"card_set"`
|
||||||
|
RoosterID string `gorm:"column_rooster_id" json:"rooster_id"`
|
||||||
|
Rooster *Rooster `gorm:"foreignKey:RoosterID" json:"rooster"`
|
||||||
|
VendorID string `gorm:"column_vendor_id" json:"vendor_id"`
|
||||||
|
Vendor Vendor `gorm:"foreignKey:VendorID" json:"vendor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (card *Card) TableName() string {
|
||||||
|
return "card"
|
||||||
|
}
|
||||||
|
|
||||||
|
type CardDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
CardNumber int `json:"card_number" binding:"required"`
|
||||||
|
Year int `json:"year" binding:"required"`
|
||||||
|
CardSetID string `json:"card_set_id" binding:"required"`
|
||||||
|
RoosterID string `json:"rooster_id" binding:"required"`
|
||||||
|
VendorID string `json:"vendor_id" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCardsToDtos(cards []Card) []CardDTO {
|
||||||
|
dtos := make([]CardDTO, len(cards))
|
||||||
|
for i, card := range cards {
|
||||||
|
dtos[i] = CardDTO{
|
||||||
|
ID: card.ID,
|
||||||
|
CreatedAt: card.CreatedAt,
|
||||||
|
UpdatedAt: card.UpdatedAt,
|
||||||
|
DeletedAt: card.DeletedAt,
|
||||||
|
Version: card.Version,
|
||||||
|
CardNumber: card.CardNumber,
|
||||||
|
Year: card.Year,
|
||||||
|
CardSetID: card.CardSetID,
|
||||||
|
RoosterID: card.RoosterID,
|
||||||
|
VendorID: card.VendorID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type CardSet struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
ParallelSet bool `gorm:"column:parallel_set" json:"parallel_set"`
|
||||||
|
InsertSet bool `gorm:"column:insert_set" json:"insert_set"`
|
||||||
|
VendorID string `gorm:"column_vendor_id" json:"vendor_id"`
|
||||||
|
Vendor Vendor `gorm:"foreignKey:VendorID" json:"vendor"`
|
||||||
|
Cards []Card `gorm:"foreignKey:CardSetID" json:"cards"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cardset *CardSet) TableName() string {
|
||||||
|
return "card_set"
|
||||||
|
}
|
||||||
|
|
||||||
|
type CardSetDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
ParallelSet bool `json:"parallel_set" binding:"required"`
|
||||||
|
InsertSet bool `json:"insert_set" binding:"required"`
|
||||||
|
VendorID string `json:"vendor_id" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertCardSetsToDtos(cardsets []CardSet) []CardSetDTO {
|
||||||
|
dtos := make([]CardSetDTO, len(cardsets))
|
||||||
|
for i, cardset := range cardsets {
|
||||||
|
dtos[i] = CardSetDTO{
|
||||||
|
ID: cardset.ID,
|
||||||
|
CreatedAt: cardset.CreatedAt,
|
||||||
|
UpdatedAt: cardset.UpdatedAt,
|
||||||
|
DeletedAt: cardset.DeletedAt,
|
||||||
|
Version: cardset.Version,
|
||||||
|
Name: cardset.Name,
|
||||||
|
ParallelSet: cardset.ParallelSet,
|
||||||
|
InsertSet: cardset.InsertSet,
|
||||||
|
VendorID: cardset.VendorID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Comic struct {
|
type Comic struct {
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
@@ -15,6 +15,7 @@ type Comic struct {
|
|||||||
Completed bool `gorm:"column:completed" json:"completed"`
|
Completed bool `gorm:"column:completed" json:"completed"`
|
||||||
WebLink string `gorm:"column:weblink" json:"weblink"`
|
WebLink string `gorm:"column:weblink" json:"weblink"`
|
||||||
PublisherID *string `gorm:"column:publisher_id" json:"publisher_id"`
|
PublisherID *string `gorm:"column:publisher_id" json:"publisher_id"`
|
||||||
|
Publisher *Publisher `gorm:"foreignKey:PublisherID"`
|
||||||
Issues []Issue `gorm:"foreignKey:ComicID"`
|
Issues []Issue `gorm:"foreignKey:ComicID"`
|
||||||
StoryArcs []StoryArc `gorm:"foreignKey:ComicID"`
|
StoryArcs []StoryArc `gorm:"foreignKey:ComicID"`
|
||||||
TradePaperbacks []TradePaperback `gorm:"foreignKey:ComicID"`
|
TradePaperbacks []TradePaperback `gorm:"foreignKey:ComicID"`
|
||||||
@@ -26,6 +27,38 @@ func (comic *Comic) TableName() string {
|
|||||||
return "comic"
|
return "comic"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ComicDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
PublisherID *string `json:"publisher_id"`
|
||||||
|
CurrentOrder bool `json:"current_order"`
|
||||||
|
Completed bool `json:"completed"`
|
||||||
|
WebLink string `json:"weblink"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertComicsToDtos(comics []Comic) []ComicDTO {
|
||||||
|
dtos := make([]ComicDTO, len(comics))
|
||||||
|
for i, comic := range comics {
|
||||||
|
dtos[i] = ComicDTO{
|
||||||
|
ID: comic.ID,
|
||||||
|
CreatedAt: comic.CreatedAt,
|
||||||
|
UpdatedAt: comic.UpdatedAt,
|
||||||
|
DeletedAt: comic.DeletedAt,
|
||||||
|
Version: comic.Version,
|
||||||
|
Title: comic.Title,
|
||||||
|
CurrentOrder: comic.CurrentOrder,
|
||||||
|
Completed: comic.Completed,
|
||||||
|
WebLink: comic.WebLink,
|
||||||
|
PublisherID: comic.PublisherID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
|
|
||||||
type CreateComicDTO struct {
|
type CreateComicDTO struct {
|
||||||
Title string `json:"title" binding:"required"`
|
Title string `json:"title" binding:"required"`
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MediaActor struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
WebLink string `gorm:"column:url" json:"url"`
|
||||||
|
|
||||||
|
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaActorID" json:"media_actor_files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (media_actor *MediaActor) TableName() string {
|
||||||
|
return "media_actor"
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaActorDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
WebLink string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertMediaActorsToDtos(actors []MediaActor) []MediaActorDTO {
|
||||||
|
dtos := make([]MediaActorDTO, len(actors))
|
||||||
|
for i, actor := range actors {
|
||||||
|
dtos[i] = MediaActorDTO{
|
||||||
|
ID: actor.ID,
|
||||||
|
CreatedAt: actor.CreatedAt,
|
||||||
|
UpdatedAt: actor.UpdatedAt,
|
||||||
|
DeletedAt: actor.DeletedAt,
|
||||||
|
Version: actor.Version,
|
||||||
|
Name: actor.Name,
|
||||||
|
WebLink: actor.WebLink,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MediaActorFile struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
MediaActorID *string `gorm:"column:media_actor_id" json:"media_actor_id"`
|
||||||
|
MediaActor *MediaActor `gorm:"foreignKey:MediaActorID" json:"media_actor"`
|
||||||
|
MediaFileID *string `form:"column:media_file_id" json:"media_file_id"`
|
||||||
|
MediaFile *MediaFile `gorm:"foreignKey:MediaFileID" json:"media_file"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (media_file *MediaActorFile) TableName() string {
|
||||||
|
return "media_actor_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaActorFileDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
MediaActorID *string `json:"media_actor_id"`
|
||||||
|
MediaFileID *string `json:"media_file_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertMediaActorFilesToDtos(actor_files []MediaActorFile) []MediaActorFileDTO {
|
||||||
|
dtos := make([]MediaActorFileDTO, len(actor_files))
|
||||||
|
for i, actor_file := range actor_files {
|
||||||
|
dtos[i] = MediaActorFileDTO{
|
||||||
|
ID: actor_file.ID,
|
||||||
|
CreatedAt: actor_file.CreatedAt,
|
||||||
|
UpdatedAt: actor_file.UpdatedAt,
|
||||||
|
DeletedAt: actor_file.DeletedAt,
|
||||||
|
Version: actor_file.Version,
|
||||||
|
MediaActorID: actor_file.MediaActorID,
|
||||||
|
MediaFileID: actor_file.MediaFileID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MediaArticle struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Review bool `gorm:"column:review" json:"review"`
|
||||||
|
Title string `gorm:"size:300, column:title" json:"title"`
|
||||||
|
WebLink string `gorm:"column:url" json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (media_article *MediaArticle) TableName() string {
|
||||||
|
return "media_article"
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaArticleDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
Review bool `json:"review"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
WebLink string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertMediaArticlesToDtos(media_articles []MediaArticle) []MediaArticleDTO {
|
||||||
|
dtos := make([]MediaArticleDTO, len(media_articles))
|
||||||
|
for i, media_article := range media_articles {
|
||||||
|
dtos[i] = MediaArticleDTO{
|
||||||
|
ID: media_article.ID,
|
||||||
|
CreatedAt: media_article.CreatedAt,
|
||||||
|
UpdatedAt: media_article.UpdatedAt,
|
||||||
|
DeletedAt: media_article.DeletedAt,
|
||||||
|
Version: media_article.Version,
|
||||||
|
Review: media_article.Review,
|
||||||
|
Title: media_article.Title,
|
||||||
|
WebLink: media_article.WebLink,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MediaFile struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
CloudLink string `gorm:"column:cloud_link" json:"cloud_link"`
|
||||||
|
FileName string `gorm:"column:file_name" json:"file_name"`
|
||||||
|
Path string `gorm:"column:path" json:"path"`
|
||||||
|
Review bool `gorm:"column:review" json:"review"`
|
||||||
|
Title string `gorm:"size:300, column:title" json:"title"`
|
||||||
|
WebLink string `gorm:"column:url" json:"url"`
|
||||||
|
ShouldDownload bool `gorm:"column:should_download" json:"should_download"`
|
||||||
|
|
||||||
|
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaFileID" json:"media_actor_files"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (media_file *MediaFile) TableName() string {
|
||||||
|
return "media_file"
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaFileDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
CloudLink string `json:"cloud_link"`
|
||||||
|
FileName string `json:"file_name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Review bool `json:"review"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
WebLink string `json:"url"`
|
||||||
|
ShouldDownload bool `json:"should_download"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertMediaFilesToDtos(media_files []MediaFile) []MediaFileDTO {
|
||||||
|
dtos := make([]MediaFileDTO, len(media_files))
|
||||||
|
for i, media_file := range media_files {
|
||||||
|
dtos[i] = MediaFileDTO{
|
||||||
|
ID: media_file.ID,
|
||||||
|
CreatedAt: media_file.CreatedAt,
|
||||||
|
UpdatedAt: media_file.UpdatedAt,
|
||||||
|
DeletedAt: media_file.DeletedAt,
|
||||||
|
Version: media_file.Version,
|
||||||
|
CloudLink: media_file.CloudLink,
|
||||||
|
FileName: media_file.FileName,
|
||||||
|
Path: media_file.Path,
|
||||||
|
Review: media_file.Review,
|
||||||
|
Title: media_file.Title,
|
||||||
|
WebLink: media_file.WebLink,
|
||||||
|
ShouldDownload: media_file.ShouldDownload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MediaLoFi struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
WebLink string `gorm:"column:url" json:"url"`
|
||||||
|
Review bool `gorm:"column:review" json:"review"`
|
||||||
|
ShouldDownload bool `gorm:"column:should_download" json:"should_download"`
|
||||||
|
Title string `gorm:"size:300, column:title" json:"title"`
|
||||||
|
FileName string `gorm:"column:file_name" json:"file_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (media_lofi *MediaLoFi) TableName() string {
|
||||||
|
return "media_lofi"
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaLoFiDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
WebLink string `json:"url"`
|
||||||
|
Review bool `json:"review"`
|
||||||
|
ShouldDownload bool `json:"should_download"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
FileName string `json:"file_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertMediaLoFisToDtos(media_lofis []MediaLoFi) []MediaLoFiDTO {
|
||||||
|
dtos := make([]MediaLoFiDTO, len(media_lofis))
|
||||||
|
for i, media_lofi := range media_lofis {
|
||||||
|
dtos[i] = MediaLoFiDTO{
|
||||||
|
ID: media_lofi.ID,
|
||||||
|
CreatedAt: media_lofi.CreatedAt,
|
||||||
|
UpdatedAt: media_lofi.UpdatedAt,
|
||||||
|
DeletedAt: media_lofi.DeletedAt,
|
||||||
|
Version: media_lofi.Version,
|
||||||
|
WebLink: media_lofi.WebLink,
|
||||||
|
Review: media_lofi.Review,
|
||||||
|
ShouldDownload: media_lofi.ShouldDownload,
|
||||||
|
Title: media_lofi.Title,
|
||||||
|
FileName: media_lofi.FileName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type MediaVideo struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
CloudLink string `gorm:"column:cloud_link" json:"cloud_link"`
|
||||||
|
FileName string `gorm:"column:file_name" json:"file_name"`
|
||||||
|
Path string `gorm:"column:path" json:"path"`
|
||||||
|
Review bool `gorm:"column:review" json:"review"`
|
||||||
|
Title string `gorm:"size:300, column:title" json:"title"`
|
||||||
|
WebLink string `gorm:"uniqueIndex,column:url" json:"url"`
|
||||||
|
ShouldDownload bool `gorm:"column:should_download" json:"should_download"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (media_video *MediaVideo) TableName() string {
|
||||||
|
return "media_video"
|
||||||
|
}
|
||||||
|
|
||||||
|
type MediaVideoDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
CloudLink string `json:"cloud_link"`
|
||||||
|
FileName string `json:"file_name"`
|
||||||
|
Path string `json:"path"`
|
||||||
|
Review bool `json:"review"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
WebLink string `json:"url"`
|
||||||
|
ShouldDownload bool `json:"should_download"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertMediaVideosToDtos(media_videos []MediaVideo) []MediaVideoDTO {
|
||||||
|
dtos := make([]MediaVideoDTO, len(media_videos))
|
||||||
|
for i, media_video := range media_videos {
|
||||||
|
dtos[i] = MediaVideoDTO{
|
||||||
|
ID: media_video.ID,
|
||||||
|
CreatedAt: media_video.CreatedAt,
|
||||||
|
UpdatedAt: media_video.UpdatedAt,
|
||||||
|
DeletedAt: media_video.DeletedAt,
|
||||||
|
Version: media_video.Version,
|
||||||
|
CloudLink: media_video.CloudLink,
|
||||||
|
FileName: media_video.FileName,
|
||||||
|
Path: media_video.Path,
|
||||||
|
Review: media_video.Review,
|
||||||
|
Title: media_video.Title,
|
||||||
|
WebLink: media_video.WebLink,
|
||||||
|
ShouldDownload: media_video.ShouldDownload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Permission struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
Assignments []Assignment `gorm:"foreignKey:PermissionID" json:"assignments"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (permission *Permission) TableName() string {
|
||||||
|
return "permission"
|
||||||
|
}
|
||||||
|
|
||||||
|
type PermissionDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
FirstName string `gorm:"column:first_name" json:"first_name"`
|
||||||
|
LastName string `gorm:"column:last_name" json:"last_name"`
|
||||||
|
Roosters []Rooster `gorm:"foreignKey:PlayerID" json:"roosters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (player *Player) TableName() string {
|
||||||
|
return "player"
|
||||||
|
}
|
||||||
|
|
||||||
|
type PlayerDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
FirstName string `json:"first_name" binding:"required"`
|
||||||
|
LastName string `json:"last_name" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertPlayersToDtos(players []Player) []PlayerDTO {
|
||||||
|
dtos := make([]PlayerDTO, len(players))
|
||||||
|
for i, player := range players {
|
||||||
|
dtos[i] = PlayerDTO{
|
||||||
|
ID: player.ID,
|
||||||
|
CreatedAt: player.CreatedAt,
|
||||||
|
UpdatedAt: player.UpdatedAt,
|
||||||
|
DeletedAt: player.DeletedAt,
|
||||||
|
Version: player.Version,
|
||||||
|
FirstName: player.FirstName,
|
||||||
|
LastName: player.LastName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Position struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
ShortName string `gorm:"column:short_name" json:"short_name"`
|
||||||
|
SportID string `gorm:"column:sport_id" json:"sport_id"`
|
||||||
|
Sport Sport `gorm:"foreignKey:SportID" json:"sport"`
|
||||||
|
Roosters []Rooster `gorm:"foreignKey:TeamID" json:"roosters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (position *Position) TableName() string {
|
||||||
|
return "field_position"
|
||||||
|
}
|
||||||
|
|
||||||
|
type PositionDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
ShortName string `json:"short_name" binding:"required"`
|
||||||
|
SportID string `json:"sport_id" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertPositionsToDtos(positions []Position) []PositionDTO {
|
||||||
|
dtos := make([]PositionDTO, len(positions))
|
||||||
|
for i, position := range positions {
|
||||||
|
dtos[i] = PositionDTO{
|
||||||
|
ID: position.ID,
|
||||||
|
CreatedAt: position.CreatedAt,
|
||||||
|
UpdatedAt: position.UpdatedAt,
|
||||||
|
DeletedAt: position.DeletedAt,
|
||||||
|
Version: position.Version,
|
||||||
|
Name: position.Name,
|
||||||
|
ShortName: position.ShortName,
|
||||||
|
SportID: position.SportID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Profile struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
First_Name *string `gorm:"column:first_name" json:"first_name"`
|
||||||
|
Last_Name *string `gorm:"column:last_name" json:"last_name"`
|
||||||
|
User_Name string `gorm:"column:user_name" json:"user_name"`
|
||||||
|
Email string `gorm:"column:email" json:"email"`
|
||||||
|
Password string `gorm:"column:password" json:"password"`
|
||||||
|
Enabled bool `gorm:"column:enabled" json:"enabled"`
|
||||||
|
|
||||||
|
Assignments []Assignment `gorm:"foreignKey:ProfileID" json:"assignments"`
|
||||||
|
Tokens []Token `gorm:"foreignKey:ProfileID" json:"tokens"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (profile *Profile) TableName() string {
|
||||||
|
return "profile"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (profile *Profile) GetFullName() string {
|
||||||
|
full_name := ""
|
||||||
|
if profile.First_Name != nil {
|
||||||
|
full_name += *profile.First_Name
|
||||||
|
}
|
||||||
|
if profile.Last_Name != nil {
|
||||||
|
full_name += " "
|
||||||
|
full_name += *profile.Last_Name
|
||||||
|
}
|
||||||
|
return full_name
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProfileDTO_ struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
First_Name *string `json:"first_name" binding:"required"`
|
||||||
|
Last_Name *string `json:"last_name" binding:"required"`
|
||||||
|
User_Name string `json:"user_name" binding:"required"`
|
||||||
|
Email string `json:"email" binding:"required"`
|
||||||
|
Password string `json:"password" binding:"required"`
|
||||||
|
Enabled bool `json:"enabled" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginInput struct {
|
||||||
|
Email string `json:"email" binding:"required"`
|
||||||
|
Password string `json:"password" binding:"required"`
|
||||||
|
}
|
||||||
+29
-1
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
@@ -20,6 +20,34 @@ func (publisher *Publisher) TableName() string {
|
|||||||
return "publisher"
|
return "publisher"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PublisherDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date"`
|
||||||
|
Version int `json:"version"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
WebLink string `json:"weblink"`
|
||||||
|
ParentPublisherID *string `json:"parent_publisher_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertPublishersToDtos(publishers []Publisher) []PublisherDTO {
|
||||||
|
dtos := make([]PublisherDTO, len(publishers))
|
||||||
|
for i, comic := range publishers {
|
||||||
|
dtos[i] = PublisherDTO{
|
||||||
|
ID: comic.ID,
|
||||||
|
CreatedAt: comic.CreatedAt,
|
||||||
|
UpdatedAt: comic.UpdatedAt,
|
||||||
|
DeletedAt: comic.DeletedAt,
|
||||||
|
Version: comic.Version,
|
||||||
|
Name: comic.Name,
|
||||||
|
WebLink: comic.WebLink,
|
||||||
|
ParentPublisherID: comic.ParentPublisherID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
|
|
||||||
type CreatePublisherDTO struct {
|
type CreatePublisherDTO struct {
|
||||||
Name string `json:"name" binding:"required"`
|
Name string `json:"name" binding:"required"`
|
||||||
WebLink string `json:"weblink" binding:"required"`
|
WebLink string `json:"weblink" binding:"required"`
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Rooster struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Year int `gorm:"column:year" json:"year"`
|
||||||
|
TeamID string `gorm:"column:team_id" json:"team_id"`
|
||||||
|
Team Team `gorm:"foreignKey:TeamID" json:"team"`
|
||||||
|
PlayerID string `gorm:"column:player_id" json:"player_id"`
|
||||||
|
Player Player `gorm:"foreignKey:PlayerID" json:"player"`
|
||||||
|
PositionID string `gorm:"column:position_id" json:"position_id"`
|
||||||
|
Position Position `gorm:"foreignKey:PositionID" json:"position"`
|
||||||
|
Cards []Card `gorm:"foreignKey:RoosterID" json:"cards"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rooster *Rooster) TableName() string {
|
||||||
|
return "rooster"
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoosterDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Year int `json:"year" binding:"required"`
|
||||||
|
TeamID string `json:"team_id" binding:"required"`
|
||||||
|
PlayerID string `json:"player_id" binding:"required"`
|
||||||
|
PositionID string `json:"position_id" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertRoostersToDtos(roosters []Rooster) []RoosterDTO {
|
||||||
|
dtos := make([]RoosterDTO, len(roosters))
|
||||||
|
for i, rooster := range roosters {
|
||||||
|
dtos[i] = RoosterDTO{
|
||||||
|
ID: rooster.ID,
|
||||||
|
CreatedAt: rooster.CreatedAt,
|
||||||
|
UpdatedAt: rooster.UpdatedAt,
|
||||||
|
DeletedAt: rooster.DeletedAt,
|
||||||
|
Version: rooster.Version,
|
||||||
|
Year: rooster.Year,
|
||||||
|
TeamID: rooster.TeamID,
|
||||||
|
PlayerID: rooster.PlayerID,
|
||||||
|
PositionID: rooster.PositionID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Sport struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"uniqueIndex" json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sport *Sport) TableName() string {
|
||||||
|
return "sport"
|
||||||
|
}
|
||||||
|
|
||||||
|
type SportDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertSportsToDtos(sports []Sport) []SportDTO {
|
||||||
|
dtos := make([]SportDTO, len(sports))
|
||||||
|
for i, sport := range sports {
|
||||||
|
dtos[i] = SportDTO{
|
||||||
|
ID: sport.ID,
|
||||||
|
CreatedAt: sport.CreatedAt,
|
||||||
|
UpdatedAt: sport.UpdatedAt,
|
||||||
|
DeletedAt: sport.DeletedAt,
|
||||||
|
Version: sport.Version,
|
||||||
|
Name: sport.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateSportDTO struct {
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
WebLink string `json:"weblink" binding:"required"`
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Team struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
ShortName string `gorm:"column:short_name" json:"short_name"`
|
||||||
|
SportID string `gorm:"column:sport_id" json:"sport_id"`
|
||||||
|
Sport Sport `gorm:"foreignKey:SportID" json:"sport"`
|
||||||
|
Roosters []Rooster `gorm:"foreignKey:TeamID" json:"roosters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (team *Team) TableName() string {
|
||||||
|
return "team"
|
||||||
|
}
|
||||||
|
|
||||||
|
type TeamDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
ShortName string `json:"short_name" binding:"required"`
|
||||||
|
SportID string `json:"sport_id" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertTeamsToDtos(teams []Team) []TeamDTO {
|
||||||
|
dtos := make([]TeamDTO, len(teams))
|
||||||
|
for i, team := range teams {
|
||||||
|
dtos[i] = TeamDTO{
|
||||||
|
ID: team.ID,
|
||||||
|
CreatedAt: team.CreatedAt,
|
||||||
|
UpdatedAt: team.UpdatedAt,
|
||||||
|
DeletedAt: team.DeletedAt,
|
||||||
|
Version: team.Version,
|
||||||
|
Name: team.Name,
|
||||||
|
ShortName: team.ShortName,
|
||||||
|
SportID: team.SportID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Token struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Token string `gorm:"uniqueIndex,column:token" json:"token"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
LastUsedAt time.Time `gorm:"column:last_used_date" json:"last_used_date"`
|
||||||
|
Enabled bool `gorm:"column.enabled" json:"enabled"`
|
||||||
|
ProfileID *string `gorm:"column:profile_id" json:"profile_id"`
|
||||||
|
Profile *Profile `gorm:"foreignKey:ProfileID" json:"profile"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (token *Token) TableName() string {
|
||||||
|
return "token"
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Token string `json:"token" binding:"required"`
|
||||||
|
ProfileID *string `json:"profile_id" binding:"required"`
|
||||||
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Vendor struct {
|
||||||
|
ID string `gorm:"type:string;primary_key;" json:"id"`
|
||||||
|
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
|
||||||
|
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
|
||||||
|
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
|
||||||
|
Version int `gorm:"default:0" json:"version"`
|
||||||
|
Name string `gorm:"column:name" json:"name"`
|
||||||
|
CardSets []CardSet `gorm:"foreignKey:VendorID" json:"card_sets"`
|
||||||
|
Cards []Card `gorm:"foreignKey:VendorID" json:"cards"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (vendor *Vendor) TableName() string {
|
||||||
|
return "vendor"
|
||||||
|
}
|
||||||
|
|
||||||
|
type VendorDTO struct {
|
||||||
|
ID string `json:"id" binding:"required"`
|
||||||
|
CreatedAt time.Time `json:"created_date" binding:"required"`
|
||||||
|
UpdatedAt time.Time `json:"last_modified_date" binding:"required"`
|
||||||
|
DeletedAt *time.Time `json:"deleted_date,omitempty" binding:"omitempty"`
|
||||||
|
Version int `json:"version" binding:"required"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConvertVendorsToDtos(vendors []Vendor) []VendorDTO {
|
||||||
|
dtos := make([]VendorDTO, len(vendors))
|
||||||
|
for i, vendor := range vendors {
|
||||||
|
dtos[i] = VendorDTO{
|
||||||
|
ID: vendor.ID,
|
||||||
|
CreatedAt: vendor.CreatedAt,
|
||||||
|
UpdatedAt: vendor.UpdatedAt,
|
||||||
|
DeletedAt: vendor.DeletedAt,
|
||||||
|
Version: vendor.Version,
|
||||||
|
Name: vendor.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtos
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package comics
|
package models
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@ package repository
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"kontor-api-gin/internal/models/comics"
|
"kontor-api-gin/internal/models"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
@@ -17,11 +17,11 @@ func NewComicRepository(db *gorm.DB) *ComicRepository {
|
|||||||
return repo
|
return repo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repository *ComicRepository) List(context context.Context) ([]comics.Comic, error) {
|
func (repository *ComicRepository) FindAll(context context.Context) ([]models.Comic, error) {
|
||||||
var comics []comics.Comic
|
var comics []models.Comic
|
||||||
|
|
||||||
result := repository.db.Find(&comics)
|
result := repository.db.Find(&comics)
|
||||||
slog.Info("ComicRepository#List", "count", result.RowsAffected)
|
slog.Info("ComicRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
return comics, nil
|
return comics, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaActorRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaActorRepository(db *gorm.DB) *MediaActorRepository {
|
||||||
|
repo := &MediaActorRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *MediaActorRepository) FindAll(context context.Context) ([]models.MediaActor, error) {
|
||||||
|
var actors []models.MediaActor
|
||||||
|
|
||||||
|
result := repository.db.Find(&actors)
|
||||||
|
slog.Info("MediaActorRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return actors, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaFileRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaFileRepository(db *gorm.DB) *MediaFileRepository {
|
||||||
|
repo := &MediaFileRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *MediaFileRepository) FindAll(context context.Context) ([]models.MediaFile, error) {
|
||||||
|
var files []models.MediaFile
|
||||||
|
|
||||||
|
result := repository.db.Find(&files)
|
||||||
|
slog.Info("MediaFileRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return files, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaLoFiRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaLoFiRepository(db *gorm.DB) *MediaLoFiRepository {
|
||||||
|
repo := &MediaLoFiRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *MediaLoFiRepository) FindAll(context context.Context) ([]models.MediaLoFi, error) {
|
||||||
|
var lofis []models.MediaLoFi
|
||||||
|
|
||||||
|
result := repository.db.Find(&lofis)
|
||||||
|
slog.Info("MediaLoFiRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return lofis, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermissionRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *PermissionRepository) FindAll(context context.Context) ([]models.Permission, error) {
|
||||||
|
|
||||||
|
var permissions []models.Permission
|
||||||
|
|
||||||
|
result := repository.db.Find(&permissions)
|
||||||
|
slog.Info("ComicRepository#List", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return permissions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPermissionRepository(db *gorm.DB) *PermissionRepository {
|
||||||
|
repository := &PermissionRepository{db: db}
|
||||||
|
return repository
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlayerRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlayerRepository(db *gorm.DB) *PlayerRepository {
|
||||||
|
repo := &PlayerRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *PlayerRepository) FindAll(context context.Context) ([]models.Player, error) {
|
||||||
|
var players []models.Player
|
||||||
|
|
||||||
|
result := repository.db.Find(&players)
|
||||||
|
slog.Info("PlayerRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return players, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *PlayerRepository) GetById(context context.Context, id string) (models.Player, error) {
|
||||||
|
var player = models.Player{ID: id}
|
||||||
|
slog.Info("PlayerRepository#GetById", "id", id)
|
||||||
|
result := repository.db.First(&player)
|
||||||
|
if result.Error != nil {
|
||||||
|
slog.Info("PlayerRepository#GetById", "error", result.Error.Error())
|
||||||
|
}
|
||||||
|
return player, result.Error
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PositionRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPositionRepository(db *gorm.DB) *PositionRepository {
|
||||||
|
repo := &PositionRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *PositionRepository) FindAll(context context.Context) ([]models.Position, error) {
|
||||||
|
var positions []models.Position
|
||||||
|
|
||||||
|
result := repository.db.Find(&positions)
|
||||||
|
slog.Info("PositionRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return positions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *PositionRepository) GetById(context context.Context, id string) (models.Position, error) {
|
||||||
|
var position = models.Position{ID: id}
|
||||||
|
slog.Info("PositionRepository#GetById", "id", id)
|
||||||
|
result := repository.db.First(&position)
|
||||||
|
if result.Error != nil {
|
||||||
|
slog.Info("PositionRepository#GetById", "error", result.Error.Error())
|
||||||
|
}
|
||||||
|
return position, result.Error
|
||||||
|
}
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -12,3 +16,23 @@ func NewProfileRepository(db *gorm.DB) *ProfileRepository {
|
|||||||
repository := &ProfileRepository{db: db}
|
repository := &ProfileRepository{db: db}
|
||||||
return repository
|
return repository
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repository *ProfileRepository) FindAll(context context.Context) ([]models.Profile, error) {
|
||||||
|
var profiles []models.Profile
|
||||||
|
|
||||||
|
result := repository.db.Find(&profiles)
|
||||||
|
slog.Info("ProfileRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return profiles, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *ProfileRepository) FindProfileByEmail(email string) (*models.Profile, error) {
|
||||||
|
var profile models.Profile
|
||||||
|
|
||||||
|
err := repository.db.Model(models.Profile{}).Where("email = ?", email).Take(&profile).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &profile, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PublisherRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPublisherRepository(db *gorm.DB) *PublisherRepository {
|
||||||
|
repo := &PublisherRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *PublisherRepository) FindAll(context context.Context) ([]models.Publisher, error) {
|
||||||
|
var publishers []models.Publisher
|
||||||
|
|
||||||
|
result := repository.db.Find(&publishers)
|
||||||
|
slog.Info("PublisherRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return publishers, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SportRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSportRepository(db *gorm.DB) *SportRepository {
|
||||||
|
repo := &SportRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *SportRepository) FindAll(context context.Context) ([]models.Sport, error) {
|
||||||
|
var sports []models.Sport
|
||||||
|
|
||||||
|
result := repository.db.Find(&sports)
|
||||||
|
slog.Info("SportRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return sports, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *SportRepository) GetById(context context.Context, id string) (models.Sport, error) {
|
||||||
|
var sport = models.Sport{ID: id}
|
||||||
|
slog.Info("SportRepository#GetById", "id", id)
|
||||||
|
result := repository.db.First(&sport)
|
||||||
|
if result.Error != nil {
|
||||||
|
slog.Info("SportRepository#GetById", "error", result.Error.Error())
|
||||||
|
}
|
||||||
|
return sport, result.Error
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TeamRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTeamRepository(db *gorm.DB) *TeamRepository {
|
||||||
|
repo := &TeamRepository{db: db}
|
||||||
|
return repo
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *TeamRepository) FindAll(context context.Context) ([]models.Team, error) {
|
||||||
|
var teams []models.Team
|
||||||
|
|
||||||
|
result := repository.db.Find(&teams)
|
||||||
|
slog.Info("TeamRepository#FindAll", "count", result.RowsAffected)
|
||||||
|
|
||||||
|
return teams, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repository *TeamRepository) GetById(context context.Context, id string) (models.Team, error) {
|
||||||
|
var team = models.Team{ID: id}
|
||||||
|
slog.Info("TeamRepository#GetById", "id", id)
|
||||||
|
result := repository.db.First(&team)
|
||||||
|
if result.Error != nil {
|
||||||
|
slog.Info("TeamRepository#GetById", "error", result.Error.Error())
|
||||||
|
}
|
||||||
|
return team, result.Error
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package router
|
|||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"kontor-api-gin/assets"
|
"kontor-api-gin/assets"
|
||||||
|
"kontor-api-gin/internal/globals"
|
||||||
"kontor-api-gin/internal/handlers"
|
"kontor-api-gin/internal/handlers"
|
||||||
"kontor-api-gin/internal/middleware"
|
"kontor-api-gin/internal/middleware"
|
||||||
"kontor-api-gin/templates"
|
"kontor-api-gin/templates"
|
||||||
@@ -11,11 +12,13 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/gin-contrib/cors"
|
"github.com/gin-contrib/cors"
|
||||||
|
"github.com/gin-contrib/sessions"
|
||||||
|
"github.com/gin-contrib/sessions/cookie"
|
||||||
gin_slog "github.com/gin-contrib/slog"
|
gin_slog "github.com/gin-contrib/slog"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func New(comics *handlers.ComicHandler, auth *handlers.AuthHandler, secret []byte) *gin.Engine {
|
func New(admin *handlers.AdminHandler, comics *handlers.ComicsHandler, media *handlers.MediaHandler, tysc *handlers.TyscHandler, webApp *handlers.WebAppHandler) *gin.Engine {
|
||||||
router := gin.New()
|
router := gin.New()
|
||||||
router.Use(gin.Recovery())
|
router.Use(gin.Recovery())
|
||||||
router.Use(gin_slog.SetLogger(
|
router.Use(gin_slog.SetLogger(
|
||||||
@@ -28,22 +31,67 @@ func New(comics *handlers.ComicHandler, auth *handlers.AuthHandler, secret []byt
|
|||||||
AllowOrigins: []string{"https://app.example.com"},
|
AllowOrigins: []string{"https://app.example.com"},
|
||||||
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"},
|
AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"},
|
||||||
AllowHeaders: []string{"Authorization", "Content-Type"},
|
AllowHeaders: []string{"Authorization", "Content-Type"},
|
||||||
|
AllowCredentials: true,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// router.LoadHTMLGlob("templates/**/*.html")
|
||||||
|
// router.Static("/public", "./assets")
|
||||||
|
|
||||||
templ := template.Must(template.New("").ParseFS(templates.TemplateFiles, "layouts/*.html", "pages/*.html"))
|
templ := template.Must(template.New("").ParseFS(templates.TemplateFiles, "layouts/*.html", "pages/*.html"))
|
||||||
router.SetHTMLTemplate(templ)
|
router.SetHTMLTemplate(templ)
|
||||||
|
|
||||||
router.StaticFS("/public", http.FS(assets.StaticFiles))
|
router.StaticFS("/public", http.FS(assets.StaticFiles))
|
||||||
|
|
||||||
router.GET("/health", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) })
|
router.Use(sessions.Sessions("session", cookie.NewStore(globals.Secret)))
|
||||||
|
router.Use(middleware.RequestID([]string{"/health"}))
|
||||||
|
|
||||||
|
router.GET("/health", handlers.Health)
|
||||||
|
router.GET("/", handlers.Index)
|
||||||
|
router.GET("/login", admin.AuthHandler.LoginPage)
|
||||||
|
router.POST("/login", admin.AuthHandler.LoginPost)
|
||||||
|
router.GET("/logout", admin.AuthHandler.LogoutPage)
|
||||||
|
|
||||||
|
comic := router.Group("/comics")
|
||||||
|
comic.GET("/comics", webApp.ComicHandler.ListPage)
|
||||||
|
|
||||||
|
m := router.Group("/web")
|
||||||
|
m.Use(middleware.AuthRequired())
|
||||||
|
m.GET("/actors", media.MediaActorHandler.ListPage)
|
||||||
|
m.GET("/articles", media.MediaFileHandler.ListPage)
|
||||||
|
m.GET("/media-files", media.MediaFileHandler.ListPage)
|
||||||
|
m.GET("/files", media.MediaFileHandler.ListPage)
|
||||||
|
m.GET("/media-lofis", media.MediaLoFiHandler.ListPage)
|
||||||
|
m.GET("/lofis", media.MediaLoFiHandler.ListPage)
|
||||||
|
|
||||||
api := router.Group("/api")
|
api := router.Group("/api")
|
||||||
api.POST("/login", auth.Login)
|
api.POST("/login", admin.AuthHandler.Login)
|
||||||
|
|
||||||
v1 := api.Group("/v1")
|
v1 := api.Group("/v1")
|
||||||
{
|
{
|
||||||
secured := v1.Group("")
|
secured := v1.Group("")
|
||||||
secured.Use(middleware.JWT(secret))
|
secured.Use(middleware.JWT(admin.Secret))
|
||||||
secured.GET("comics/comics", comics.List)
|
secured.GET("admin/permissions", admin.PermissionHandler.List)
|
||||||
|
secured.GET("tysc/sports", tysc.SportHandler.List)
|
||||||
|
secured.GET("tysc/sports/:id", tysc.SportHandler.Get)
|
||||||
|
secured.GET("tysc/players", tysc.PlayerHandler.List)
|
||||||
|
secured.GET("tysc/teams", tysc.TeamHandler.List)
|
||||||
|
secured.GET("tysc/positions", tysc.PositionHandler.List)
|
||||||
|
// secured.GET("tysc/roosters", tysc.RoosterHandler.List)
|
||||||
|
// secured.GET("tysc/vendors", tysc.VendorHandler.List)
|
||||||
|
// secured.GET("tysc/cardsets", tysc.CardSetHandler.List)
|
||||||
|
// secured.GET("tysc/cards", tysc.CardHandler.List)
|
||||||
|
secured.GET("/comics/comics", comics.ComicHandler.List)
|
||||||
|
secured.GET("/comics/publishers", comics.PublisherHandler.List)
|
||||||
|
// comic.GET("/artists", comics.ArtistHandler.List)
|
||||||
|
// comic.GET("/issues", comics.IssueHandler.List)
|
||||||
|
// comic.GET("/worktypes", comics.WorktypeHandler.List)
|
||||||
|
// comic.GET("/volumes", comics.VolumeHandler.List)
|
||||||
|
// comic.GET("/storyarcs", comics.StoryarcHandler.List)
|
||||||
|
// comic.GET("/comicworks", comics.ComicworkHandler.List)
|
||||||
|
// comic.GET("/issueworks", comics.IssueworkHandler.List)
|
||||||
|
secured.GET("/media/files", media.MediaFileHandler.List)
|
||||||
|
secured.GET("/media/lofis", media.MediaLoFiHandler.List)
|
||||||
|
secured.GET("/media/actors", media.MediaActorHandler.List)
|
||||||
}
|
}
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import "kontor-api-gin/internal/repository"
|
import (
|
||||||
|
"kontor-api-gin/internal/helpers"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
type AuthService struct {
|
type AuthService struct {
|
||||||
repository *repository.ProfileRepository
|
repository *repository.ProfileRepository
|
||||||
@@ -10,3 +15,33 @@ func NewAuthService(repository *repository.ProfileRepository, secret []byte) *Au
|
|||||||
service := &AuthService{repository: repository}
|
service := &AuthService{repository: repository}
|
||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func VerifyPassword(password, hashedPassword string) error {
|
||||||
|
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *AuthService) LoginCheck(email string, password string) (string, error) {
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
profile, err := service.repository.FindProfileByEmail(email)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = VerifyPassword(password, profile.Password)
|
||||||
|
|
||||||
|
if err != nil && err == bcrypt.ErrMismatchedHashAndPassword {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := helpers.GenerateToken(profile.ID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return token, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"kontor-api-gin/internal/models/comics"
|
"kontor-api-gin/internal/models"
|
||||||
"kontor-api-gin/internal/repository"
|
"kontor-api-gin/internal/repository"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
)
|
)
|
||||||
@@ -16,7 +16,7 @@ func NewComicService(repo *repository.ComicRepository) *ComicService {
|
|||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
|
|
||||||
func (service *ComicService) List(context context.Context) ([]comics.Comic, error) {
|
func (service *ComicService) List(context context.Context) ([]models.Comic, error) {
|
||||||
slog.Info("ComicService#List")
|
slog.Info("ComicService#List")
|
||||||
return service.repository.List(context)
|
return service.repository.FindAll(context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaActorService struct {
|
||||||
|
repository *repository.MediaActorRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaActorService(repo *repository.MediaActorRepository) *MediaActorService {
|
||||||
|
service := &MediaActorService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *MediaActorService) List(context context.Context) ([]models.MediaActor, error) {
|
||||||
|
slog.Info("MediaActorService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaFileService struct {
|
||||||
|
repository *repository.MediaFileRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaFileService(repo *repository.MediaFileRepository) *MediaFileService {
|
||||||
|
service := &MediaFileService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *MediaFileService) List(context context.Context) ([]models.MediaFile, error) {
|
||||||
|
slog.Info("MediaFileService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MediaLoFiService struct {
|
||||||
|
repository *repository.MediaLoFiRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMediaLoFiService(repo *repository.MediaLoFiRepository) *MediaLoFiService {
|
||||||
|
service := &MediaLoFiService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *MediaLoFiService) List(context context.Context) ([]models.MediaLoFi, error) {
|
||||||
|
slog.Info("MediaLoFiService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermissionService struct {
|
||||||
|
repository *repository.PermissionRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPermissionService(repository *repository.PermissionRepository) *PermissionService {
|
||||||
|
service := &PermissionService{repository: repository}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service PermissionService) List(context context.Context) ([]models.Permission, error) {
|
||||||
|
slog.Info("ComicService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PlayerService struct {
|
||||||
|
repository *repository.PlayerRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPlayerService(repo *repository.PlayerRepository) *PlayerService {
|
||||||
|
service := &PlayerService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *PlayerService) List(context context.Context) ([]models.Player, error) {
|
||||||
|
slog.Info("PlayerService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *PlayerService) Get(context context.Context, id string) (models.Player, error) {
|
||||||
|
slog.Info("PlayerService#Get")
|
||||||
|
return service.repository.GetById(context, id)
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PositionService struct {
|
||||||
|
repository *repository.PositionRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPositionService(repo *repository.PositionRepository) *PositionService {
|
||||||
|
service := &PositionService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *PositionService) List(context context.Context) ([]models.Position, error) {
|
||||||
|
slog.Info("PositionService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *PositionService) Get(context context.Context, id string) (models.Position, error) {
|
||||||
|
slog.Info("PositionService#Get")
|
||||||
|
return service.repository.GetById(context, id)
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PublisherService struct {
|
||||||
|
repository *repository.PublisherRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPublisherService(repo *repository.PublisherRepository) *PublisherService {
|
||||||
|
service := &PublisherService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *PublisherService) List(context context.Context) ([]models.Publisher, error) {
|
||||||
|
slog.Info("PublisherService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SportService struct {
|
||||||
|
repository *repository.SportRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSportService(repo *repository.SportRepository) *SportService {
|
||||||
|
service := &SportService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *SportService) List(context context.Context) ([]models.Sport, error) {
|
||||||
|
slog.Info("SportService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *SportService) Get(context context.Context, id string) (models.Sport, error) {
|
||||||
|
slog.Info("SportService#Get")
|
||||||
|
return service.repository.GetById(context, id)
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"kontor-api-gin/internal/models"
|
||||||
|
"kontor-api-gin/internal/repository"
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TeamService struct {
|
||||||
|
repository *repository.TeamRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTeamService(repo *repository.TeamRepository) *TeamService {
|
||||||
|
service := &TeamService{repository: repo}
|
||||||
|
return service
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *TeamService) List(context context.Context) ([]models.Team, error) {
|
||||||
|
slog.Info("TeamService#List")
|
||||||
|
return service.repository.FindAll(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (service *TeamService) Get(context context.Context, id string) (models.Team, error) {
|
||||||
|
slog.Info("TeamService#Get")
|
||||||
|
return service.repository.GetById(context, id)
|
||||||
|
}
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/globals"
|
|
||||||
"kontor-api-gin/pkg/helpers"
|
|
||||||
"kontor-api-gin/pkg/schema"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/sessions"
|
|
||||||
"github.com/gin-contrib/slog"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LoginInput struct {
|
|
||||||
Email string `json:"email" binding:"required"`
|
|
||||||
Password string `json:"password" binding:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoginHandler(c *gin.Context) {
|
|
||||||
var input LoginInput
|
|
||||||
|
|
||||||
if err := c.ShouldBindJSON(&input); err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
profile := schema.Profile{}
|
|
||||||
|
|
||||||
profile.Email = input.Email
|
|
||||||
profile.Password = input.Password
|
|
||||||
|
|
||||||
token, err := schema.LoginCheck(profile.Email, profile.Password)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
c.JSON(http.StatusBadRequest, gin.H{"error": "username or password is incorrect."})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, gin.H{"token": token})
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoginGetHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
logger.Info("LoginGetHandler", globals.UserKey, user)
|
|
||||||
if user != nil {
|
|
||||||
c.HTML(http.StatusBadRequest, "login", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"message": "Please logout first",
|
|
||||||
"user": user,
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.HTML(http.StatusOK, "login", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"message": "",
|
|
||||||
"user": user,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoginPostHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
logger.Info("LoginPostHandler", "user", user)
|
|
||||||
if user != nil {
|
|
||||||
c.HTML(http.StatusBadRequest, "login", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"message": "Please logout first",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
username := c.PostForm("username")
|
|
||||||
password := c.PostForm("password")
|
|
||||||
|
|
||||||
if helpers.EmptyUserPass(username, password) {
|
|
||||||
c.HTML(http.StatusBadRequest, "login", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"message": "Parameters can't be empty",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if !helpers.CheckUserPass(username, password) {
|
|
||||||
c.HTML(http.StatusUnauthorized, "login", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"message": "Incorrect username or password",
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
session.Set(globals.UserKey, username)
|
|
||||||
if err := session.Save(); err != nil {
|
|
||||||
c.HTML(http.StatusInternalServerError, "login", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"message": "Failed to save session",
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logger.Info("LoginGetHandler: redirect to index")
|
|
||||||
|
|
||||||
c.Redirect(http.StatusMovedPermanently, "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
func LogoutGetHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
logger.Info("LogoutGetHandler", globals.UserKey, user)
|
|
||||||
if user == nil {
|
|
||||||
logger.Info("Invalid session token")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
session.Delete(globals.UserKey)
|
|
||||||
if err := session.Save(); err != nil {
|
|
||||||
logger.Info("Failed to save session", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logger.Info("LogoutGetHandler: redirect to index page")
|
|
||||||
c.Redirect(http.StatusMovedPermanently, "/")
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/globals"
|
|
||||||
"kontor-api-gin/pkg/schema"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/sessions"
|
|
||||||
"github.com/gin-contrib/slog"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ListComicsGetHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
|
|
||||||
var comics []schema.Comic
|
|
||||||
|
|
||||||
result := schema.DB.Find(&comics)
|
|
||||||
logger.Info("ListComicsGetHandler", "count", result.RowsAffected)
|
|
||||||
c.HTML(http.StatusOK, "comics", gin.H{
|
|
||||||
"title": "Kontor Comics",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"message": "Comics...",
|
|
||||||
"comics": comics,
|
|
||||||
"user": user,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/schema"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/slog"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ListComics(c *gin.Context) {
|
|
||||||
var comics []schema.Comic
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
// query := schema.DB.Model(&schema.MediaFile{})
|
|
||||||
// result := query.Find(&files)
|
|
||||||
result := schema.DB.Find(&comics)
|
|
||||||
logger.Info("found Comics", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, comics)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicPublishers(c *gin.Context) {
|
|
||||||
var publishers []schema.Publisher
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&publishers)
|
|
||||||
logger.Info("found Comic Publishers", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, publishers)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicArtists(c *gin.Context) {
|
|
||||||
var artists []schema.Artist
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&artists)
|
|
||||||
logger.Info("found Comic Artists", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, artists)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicIssues(c *gin.Context) {
|
|
||||||
var issues []schema.Issue
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&issues)
|
|
||||||
logger.Info("found Comic Issues", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, issues)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicWorkTypes(c *gin.Context) {
|
|
||||||
var worktypes []schema.WorkType
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&worktypes)
|
|
||||||
logger.Info("found Comic WorkTypes", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, worktypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicVolumes(c *gin.Context) {
|
|
||||||
var items []schema.Volume
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&items)
|
|
||||||
logger.Info("found Comic Volumes", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicStoryArcs(c *gin.Context) {
|
|
||||||
var items []schema.StoryArc
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&items)
|
|
||||||
logger.Info("ListComicStoryArcs", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicWorks(c *gin.Context) {
|
|
||||||
var items []schema.ComicWork
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&items)
|
|
||||||
logger.Info("found Comic ComicWorks", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, items)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListComicIssueWorks(c *gin.Context) {
|
|
||||||
var items []schema.IssueWork
|
|
||||||
|
|
||||||
logger := slog.Get(c)
|
|
||||||
result := schema.DB.Find(&items)
|
|
||||||
logger.Info("found Comic IssueWorks", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, items)
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/globals"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func HealthGetHandler(c *gin.Context) {
|
|
||||||
c.JSON(http.StatusOK, gin.H{
|
|
||||||
"status": "healthy",
|
|
||||||
"version": globals.Version,
|
|
||||||
"time": time.Now().UTC().Format(time.RFC3339),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/globals"
|
|
||||||
"kontor-api-gin/pkg/schema"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/sessions"
|
|
||||||
"github.com/gin-contrib/slog"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ListMediaFiles(c *gin.Context) {
|
|
||||||
var files []schema.MediaFile
|
|
||||||
logger := slog.Get(c)
|
|
||||||
|
|
||||||
// query := schema.DB.Model(&schema.MediaFile{})
|
|
||||||
// result := query.Find(&files)
|
|
||||||
result := schema.DB.Find(&files)
|
|
||||||
logger.Info("ListMediaFiles", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, files)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListMediaLoFis(c *gin.Context) {
|
|
||||||
var lofis []schema.MediaLoFi
|
|
||||||
logger := slog.Get(c)
|
|
||||||
|
|
||||||
result := schema.DB.Find(&lofis)
|
|
||||||
logger.Info("ListMediaLoFis", "count", result.RowsAffected)
|
|
||||||
c.JSON(http.StatusOK, lofis)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListMediaActorsGetHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
|
|
||||||
var actors []schema.MediaActor
|
|
||||||
|
|
||||||
result := schema.DB.Find(&actors)
|
|
||||||
logger.Info("ListMediaActorsGetHandler", "count", result.RowsAffected)
|
|
||||||
c.HTML(http.StatusOK, "mediaactors", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"message": "Media Actors...",
|
|
||||||
"actors": actors,
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"logout": globals.LogoutUrl,
|
|
||||||
"user": user,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListMediaFilesGetHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
|
|
||||||
var files []schema.MediaFile
|
|
||||||
|
|
||||||
result := schema.DB.Find(&files)
|
|
||||||
logger.Info("ListMediaFilesGetHandler", "count", result.RowsAffected)
|
|
||||||
c.HTML(http.StatusOK, "mediafiles", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"message": "Media Files...",
|
|
||||||
"files": files,
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"logout": globals.LogoutUrl,
|
|
||||||
"user": user,
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListMediaLoFisGetHandler(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
|
|
||||||
var lofis []schema.MediaLoFi
|
|
||||||
|
|
||||||
result := schema.DB.Find(&lofis)
|
|
||||||
logger.Info("ListMediaLoFisGetHandler", "count", result.RowsAffected)
|
|
||||||
logger.Info("ListMediaLoFisGetHandler", "medialofi", lofis[0])
|
|
||||||
c.HTML(http.StatusOK, "lofi", gin.H{
|
|
||||||
"title": "Kontor Gin",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"message": "Media LoFis...",
|
|
||||||
"lofis": lofis,
|
|
||||||
"login": globals.LoginUrl,
|
|
||||||
"logout": globals.LogoutUrl,
|
|
||||||
"user": user,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
// corsMiddleware adds CORS headers for cross-origin requests
|
|
||||||
func CorsMiddleware(c *gin.Context) {
|
|
||||||
c.Header("Access-Control-Allow-Origin", "*")
|
|
||||||
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
|
||||||
c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
|
||||||
c.Header("Access-Control-Allow-Credentials", "true")
|
|
||||||
|
|
||||||
// Handle preflight requests
|
|
||||||
if c.Request.Method == "OPTIONS" {
|
|
||||||
c.AbortWithStatus(http.StatusNoContent)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Next()
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
package middleware
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/internal/globals"
|
|
||||||
"kontor-api-gin/internal/helpers"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gin-contrib/sessions"
|
|
||||||
"github.com/gin-contrib/slog"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func AuthRequired(c *gin.Context) {
|
|
||||||
session := sessions.Default(c)
|
|
||||||
user := session.Get(globals.UserKey)
|
|
||||||
logger := slog.Get(c)
|
|
||||||
logger.Info("AuthRequired", globals.UserKey, user)
|
|
||||||
if user == nil {
|
|
||||||
logger.Info("User not logged in")
|
|
||||||
c.Redirect(http.StatusMovedPermanently, globals.LoginUrl)
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Next()
|
|
||||||
}
|
|
||||||
|
|
||||||
func JwtRequired(c *gin.Context) {
|
|
||||||
logger := slog.Get(c)
|
|
||||||
err := helpers.TokenValid(c)
|
|
||||||
logger.Info("JwtRequired", "TokenValid", err)
|
|
||||||
if err != nil {
|
|
||||||
c.String(http.StatusUnauthorized, "Unauthorized")
|
|
||||||
c.Abort()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c.Next()
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/controllers"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SetupApiRoutes(router *gin.Engine) *gin.RouterGroup {
|
|
||||||
api := router.Group("/api")
|
|
||||||
api.POST("/login", controllers.LoginHandler)
|
|
||||||
v1 := api.Group("/v1")
|
|
||||||
return v1
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/controllers"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SetupComicRoutes(router *gin.RouterGroup) {
|
|
||||||
comic := router.Group("/comics")
|
|
||||||
|
|
||||||
comics := comic.Group("/comics")
|
|
||||||
comics.GET("", controllers.ListComics)
|
|
||||||
publishers := comic.Group("/publishers")
|
|
||||||
publishers.GET("", controllers.ListComicPublishers)
|
|
||||||
artists := comic.Group("/artists")
|
|
||||||
artists.GET("/", controllers.ListComicArtists)
|
|
||||||
issues := comic.Group("/issues")
|
|
||||||
issues.GET("", controllers.ListComicIssues)
|
|
||||||
worktypes := comic.Group("/worktypes")
|
|
||||||
worktypes.GET("", controllers.ListComicWorkTypes)
|
|
||||||
volumes := comic.Group("/volumes")
|
|
||||||
volumes.GET("", controllers.ListComicVolumes)
|
|
||||||
storyarcs := comic.Group("/storyarcs")
|
|
||||||
storyarcs.GET("", controllers.ListComicStoryArcs)
|
|
||||||
comicworks := comic.Group("/comicworks")
|
|
||||||
comicworks.GET("", controllers.ListComicWorks)
|
|
||||||
issueworks := comic.Group("/issueworks")
|
|
||||||
issueworks.GET("", controllers.ListComicIssueWorks)
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/controllers"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SetupMediaRoutes(router *gin.RouterGroup) {
|
|
||||||
media := router.Group("/media")
|
|
||||||
|
|
||||||
files := media.Group("/files")
|
|
||||||
files.GET("", controllers.ListMediaFiles)
|
|
||||||
|
|
||||||
lofi := media.Group("/lofi")
|
|
||||||
lofi.GET("/", controllers.ListMediaLoFis)
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package routes
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/pkg/controllers"
|
|
||||||
"kontor-api-gin/pkg/globals"
|
|
||||||
"kontor-api-gin/pkg/middleware"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PublicRoutes(g *gin.Engine) {
|
|
||||||
g.GET("/health", controllers.HealthGetHandler)
|
|
||||||
g.GET(globals.LoginUrl, controllers.LoginGetHandler)
|
|
||||||
g.POST(globals.LoginUrl, controllers.LoginPostHandler)
|
|
||||||
g.GET("/", controllers.IndexGetHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComicRoutes(g *gin.Engine) {
|
|
||||||
g.GET("/comic/comics", controllers.ListComicsGetHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MediaRoutes(g *gin.Engine) {
|
|
||||||
media := g.Group("/media")
|
|
||||||
media.Use(middleware.AuthRequired)
|
|
||||||
media.GET("/actors", controllers.ListMediaActorsGetHandler)
|
|
||||||
media.GET("/files", controllers.ListMediaFilesGetHandler)
|
|
||||||
media.GET("/lofis", controllers.ListMediaLoFisGetHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func AuthRoutes(g *gin.Engine) {
|
|
||||||
auth := g.Group("/auth")
|
|
||||||
auth.Use(middleware.AuthRequired)
|
|
||||||
auth.GET("/logout", controllers.LogoutGetHandler)
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package schema
|
|
||||||
|
|
||||||
import (
|
|
||||||
"kontor-api-gin/internal/helpers"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func VerifyPassword(password, hashedPassword string) error {
|
|
||||||
return bcrypt.CompareHashAndPassword([]byte(hashedPassword), []byte(password))
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoginCheck(email string, password string) (string, error) {
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
profile := Profile{}
|
|
||||||
|
|
||||||
err = DB.Model(Profile{}).Where("email = ?", email).Take(&profile).Error
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = VerifyPassword(password, profile.Password)
|
|
||||||
|
|
||||||
if err != nil && err == bcrypt.ErrMismatchedHashAndPassword {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
token, err := helpers.GenerateToken(profile.ID)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return token, nil
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type Profile struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
First_Name *string `json:"first_name"`
|
|
||||||
Last_Name *string `json:"last_name"`
|
|
||||||
User_Name string `json:"user_name"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Enabled bool `json:"enabled"`
|
|
||||||
|
|
||||||
Assignments []Assignment `gorm:"foreignKey:ProfileID" json:"assignments"`
|
|
||||||
Tokens []Token `gorm:"foreignKey:ProfileID" json:"tokens"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (profile *Profile) TableName() string {
|
|
||||||
return "profile"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (profile *Profile) GetFullName() string {
|
|
||||||
full_name := ""
|
|
||||||
if profile.First_Name != nil {
|
|
||||||
full_name += *profile.First_Name
|
|
||||||
}
|
|
||||||
if profile.Last_Name != nil {
|
|
||||||
full_name += " "
|
|
||||||
full_name += *profile.Last_Name
|
|
||||||
}
|
|
||||||
return full_name
|
|
||||||
}
|
|
||||||
|
|
||||||
type Token struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
Token string `gorm:"uniqueIndex" json:"token"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Last_Used_date time.Time `json:"last_used_date"`
|
|
||||||
Enabled bool `json:"enabled"`
|
|
||||||
ProfileID *string `json:"profile_id"`
|
|
||||||
Profile *Profile `gorm:"foreignKey:ProfileID" json:"profile"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (token *Token) TableName() string {
|
|
||||||
return "token"
|
|
||||||
}
|
|
||||||
|
|
||||||
type Permission struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Assignments []Assignment `gorm:"foreignKey:PermissionID" json:"assignments"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (permission *Permission) TableName() string {
|
|
||||||
return "permission"
|
|
||||||
}
|
|
||||||
|
|
||||||
type Assignment struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
ProfileID *string `json:"profile_id"`
|
|
||||||
Profile *Profile `gorm:"foreignKey:ProfileID" json:"profile"`
|
|
||||||
PermissionID *string `json:"permission_id"`
|
|
||||||
Permission *Profile `gorm:"foreignKey:PermissionID" json:"permission"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (assignment *Assignment) TableName() string {
|
|
||||||
return "assignment"
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package schema
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Base struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
CreatedAt time.Time `json:"created_date"`
|
|
||||||
UpdatedAt time.Time `json:"last_modified_date"`
|
|
||||||
DeletedAt *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeforeCreate will set a UUID rather than numeric ID.
|
|
||||||
func (b *Base) BeforeCreate(tx *gorm.DB) (err error) {
|
|
||||||
b.ID = uuid.New().String()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package schema
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"log/slog"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
"gorm.io/driver/postgres"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"gorm.io/gorm/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DB *gorm.DB
|
|
||||||
|
|
||||||
func Connect() {
|
|
||||||
// Build the connection string from environment variables
|
|
||||||
// This keeps sensitive credentials out of the codebase
|
|
||||||
dsn := fmt.Sprintf(
|
|
||||||
"host=%s user=%s password=%s dbname=%s port=%d sslmode=disable",
|
|
||||||
viper.GetString("db.host"),
|
|
||||||
viper.GetString("db.user"),
|
|
||||||
viper.GetString("db.password"),
|
|
||||||
viper.GetString("db.name"),
|
|
||||||
viper.GetInt("db.port"),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Configure GORM with custom settings
|
|
||||||
// The logger helps with debugging SQL queries during development
|
|
||||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
|
|
||||||
Logger: logger.Default.LogMode(logger.Info),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to connect to database:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the underlying SQL database connection for pool configuration
|
|
||||||
sqlDB, err := db.DB()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to get database instance:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure connection pool settings
|
|
||||||
// MaxIdleConns: number of connections kept open when idle
|
|
||||||
sqlDB.SetMaxIdleConns(10)
|
|
||||||
// MaxOpenConns: maximum total connections to the database
|
|
||||||
sqlDB.SetMaxOpenConns(100)
|
|
||||||
// ConnMaxLifetime: how long a connection can be reused
|
|
||||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
|
||||||
|
|
||||||
DB = db
|
|
||||||
slog.Info("Database connected successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunMigrations() {
|
|
||||||
// AutoMigrate creates tables, missing columns, and missing indexes
|
|
||||||
// It will NOT delete unused columns to protect your data
|
|
||||||
err := DB.AutoMigrate()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Migration failed:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Info("Database migration completed")
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
package schema
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
type MediaLoFi struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
Url string `gorm:"uniqueIndex" json:"url"`
|
|
||||||
Review bool `json:"review"`
|
|
||||||
ShouldDownload bool `json:"should_download"`
|
|
||||||
Title string `gorm:"size:300" json:"title"`
|
|
||||||
FileName string `json:"file_name"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (media_lofi *MediaLoFi) TableName() string {
|
|
||||||
return "media_lofi"
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaFile struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
CloudLink string `gorm:"column:cloud_link" json:"cloud_link"`
|
|
||||||
FileName string `json:"file_name"`
|
|
||||||
Path string `json:"path"`
|
|
||||||
Review bool `json:"review"`
|
|
||||||
Title string `gorm:"size:300" json:"title"`
|
|
||||||
WebLink string `gorm:"column:url" json:"url"`
|
|
||||||
ShouldDownload bool `json:"should_download"`
|
|
||||||
|
|
||||||
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaFileID" json:"media_actor_files"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (media_file *MediaFile) TableName() string {
|
|
||||||
return "media_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaActor struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
|
|
||||||
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaActorID" json:"media_actor_files"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (media_actor *MediaActor) TableName() string {
|
|
||||||
return "media_actor"
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaActorFile struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
MediaActorID *string `json:"media_actor_id"`
|
|
||||||
MediaActor *MediaActor `gorm:"foreignKey:MediaActorID" json:"media_actor"`
|
|
||||||
MediaFileID *string `json:"media_file_id"`
|
|
||||||
MediaFile *MediaFile `gorm:"foreignKey:MediaFileID" json:"media_file"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (media_file *MediaActorFile) TableName() string {
|
|
||||||
return "media_actor_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaArticle struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
Review bool `json:"review"`
|
|
||||||
Title string `gorm:"size:300" json:"title"`
|
|
||||||
Url string `gorm:"uniqueIndex" json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (media_article *MediaArticle) TableName() string {
|
|
||||||
return "media_article"
|
|
||||||
}
|
|
||||||
|
|
||||||
type MediaVideo struct {
|
|
||||||
ID string `gorm:"type:string;primary_key;"`
|
|
||||||
Created_Date time.Time `json:"created_date"`
|
|
||||||
Last_Modified_date time.Time `json:"last_modified_date"`
|
|
||||||
Deleted_Date *time.Time `json:"deleted_date"`
|
|
||||||
Version int `gorm:"default:0" json:"version"`
|
|
||||||
CloudLink string `json:"cloud_link"`
|
|
||||||
FileName string `json:"file_name"`
|
|
||||||
Path string `json:"path"`
|
|
||||||
Review bool `json:"review"`
|
|
||||||
Title string `gorm:"size:300" json:"title"`
|
|
||||||
Url string `gorm:"uniqueIndex" json:"url"`
|
|
||||||
ShouldDownload bool `json:"should_download"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (media_video *MediaVideo) TableName() string {
|
|
||||||
return "media_video"
|
|
||||||
}
|
|
||||||
@@ -1,32 +1,34 @@
|
|||||||
{{ define "navbar" }}
|
{{ define "navbar" }}
|
||||||
<div class="container">
|
|
||||||
<nav class="navbar fixed-top navbar-expand-lg navbar-dark" style="background-color: darkgrey;">
|
<nav class="navbar fixed-top navbar-expand-lg navbar-dark" style="background-color: darkgrey;">
|
||||||
<a class="navbar-brand" href="/">Kontor</a>
|
<a class="navbar-brand" href="/">Kontor</a>
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-item nav-link" href="/comic/comics">Comics</a>
|
<a class="nav-item nav-link" href="/">Kontor</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Media</a>
|
<a class="nav-link dropdown-toggle" href="#" id="navbarComicsMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Comics</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
|
<div class="dropdown-menu" aria-labelledby="navbarComicsMenuLink">
|
||||||
<a class="dropdown-item" href="/media/files">Media Files</a>
|
<a class="dropdown-item" href="/comics/comics">Comics</a>
|
||||||
<a class="dropdown-item" href="/media/actors">Media Actors</a>
|
<a class="dropdown-item" href="/comics/publishers">Publisher</a>
|
||||||
<a class="dropdown-item" href="/media/lofis">Lofi</a>
|
<a class="dropdown-item" href="/comics/artists">Artist</a>
|
||||||
|
<a class="dropdown-item" href="/comics/issues">Issue</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link" href="/media/files">Media</a>
|
<a class="nav-link dropdown-toggle" href="#" id="navbarWebMenuLink" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Media</a>
|
||||||
</li>
|
<div class="dropdown-menu" aria-labelledby="navbarWebMenuLink">
|
||||||
<li class="nav-item">
|
<a class="dropdown-item" href="/web/files">Media Files</a>
|
||||||
<a class="nav-link" href="/media/lofis">Lofis</a>
|
<a class="dropdown-item" href="/web/actors">Media Actors</a>
|
||||||
|
<a class="dropdown-item" href="/web/lofis">Lofi</a>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{{ if .user }}
|
{{ if .user }}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ .logout }}">Logout</a>
|
<a class="nav-link" href="/logout">Logout</a>
|
||||||
</li>
|
</li>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ .login }}">Login</a>
|
<a class="nav-link" href="/login">Login</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<form class="form-inline">
|
<form class="form-inline">
|
||||||
@@ -35,6 +37,4 @@
|
|||||||
</form>
|
</form>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@@ -36,8 +36,8 @@
|
|||||||
{{ range .lofis }}
|
{{ range .lofis }}
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><a href="/media/lofis/{{.ID}}">{{.Title}}</a></th>
|
<th scope="row"><a href="/media/lofis/{{.ID}}">{{.Title}}</a></th>
|
||||||
{{ if .Url }}
|
{{ if .WebLink }}
|
||||||
<td><a href="{{.Url}}">{{.Url}}</a></td>
|
<td><a href="{{.WebLink}}">{{.WebLink}}</a></td>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<td>WebLink not set</td>
|
<td>WebLink not set</td>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@@ -5,7 +5,76 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{ template "navbar" . }}
|
{{ template "navbar" . }}
|
||||||
|
<div class="row">
|
||||||
|
<form class="form-inline" action="/web/files">
|
||||||
|
<input type="text" placeholder="Search" name="query">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="review" {{ if .Review }}checked{{ end }}>Review
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="download" {{ if .ShouldDownload }}checked{{ end }}>Download
|
||||||
|
</label>
|
||||||
|
<button type="submit">Search</button>
|
||||||
|
<div class="pill-nav"><a href="/web/files/add">Add MediaFile</a></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="maincolumn">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Title</th>
|
||||||
|
<th scope="col">Weblink</th>
|
||||||
|
<th scope="col">Review</th>
|
||||||
|
<th scope="col">Download</th>
|
||||||
|
<th colspan="2">Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{ range .mediafiles }}
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><a href="/web/files/{{.ID}}">{{.Title}}</a></th>
|
||||||
|
{{ if .WebLink }}
|
||||||
|
<td><a href="{{.WebLink}}">{{.WebLink}}</a></td>
|
||||||
|
{{ else }}
|
||||||
|
<td>no link</td>
|
||||||
|
{{ end }}
|
||||||
|
<td>
|
||||||
|
{{ if .Review }}
|
||||||
|
<img src="/public/icons/tick.png" alt="true" width="24" height="24">
|
||||||
|
{{ else }}
|
||||||
|
<img src="/public/icons/cross.png" alt="true" width="24" height="24">
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ if .ShouldDownload }}
|
||||||
|
<img src="/public/icons/tick.png" alt="true" width="24" height="24">
|
||||||
|
{{ else }}
|
||||||
|
<img src="/public/icons/cross.png" alt="true" width="24" height="24">
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
|
<td><a href="/web/files/edit/{{.ID}}" class="btn btn-outline-primary btn-sm active" role="button"
|
||||||
|
aria-pressed="true">Edit</a></td>
|
||||||
|
<td><a href="/web/files/delete/{{.ID}}" class="btn btn-outline-danger btn-sm active"
|
||||||
|
role="button" aria-pressed="true">Delete</a></td>
|
||||||
|
</tr>
|
||||||
|
{{ end }}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ template "footer" . }}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{{ template "navbar" . }}
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
<h1>{{ .message }}</h1>
|
<h1>{{ .message }}</h1>
|
||||||
|
<h1>{{ .message }}</h1>
|
||||||
|
<h1>{{ .message }}</h1>
|
||||||
|
<h1>{{ .message }}</h1>
|
||||||
|
</div>
|
||||||
{{ template "footer" . }}
|
{{ template "footer" . }}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ Documentation=man:podman-generate-systemd(1)
|
|||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
After=network-online.target
|
After=network-online.target
|
||||||
RequiresMountsFor=/run/user/1000/containers
|
RequiresMountsFor=/run/user/1000/containers
|
||||||
Wants=kontor-activemq.service kontor-adminer.service kontor-angular.service kontor-api.service kontor-echo.service kontor-fiber.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service
|
Wants=kontor-activemq.service kontor-adminer.service kontor-angular.service kontor-api.service kontor-echo.service kontor-fiber.service kontor-gin.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service
|
||||||
Before=kontor-activemq.service kontor-adminer.service kontor-angular.service kontor-api.service kontor-echo.service kontor-fiber.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service
|
Before=kontor-activemq.service kontor-adminer.service kontor-angular.service kontor-api.service kontor-echo.service kontor-fiber.service kontor-gin.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=PODMAN_SYSTEMD_UNIT=%n
|
Environment=PODMAN_SYSTEMD_UNIT=%n
|
||||||
@@ -27,6 +27,7 @@ ExecStartPre=/usr/bin/podman pod create \
|
|||||||
-p 8300:8300 \
|
-p 8300:8300 \
|
||||||
-p 8400:8400 \
|
-p 8400:8400 \
|
||||||
-p 8500:8500 \
|
-p 8500:8500 \
|
||||||
|
-p 8550:8550 \
|
||||||
-p 8600:8600 \
|
-p 8600:8600 \
|
||||||
-p 8700:8700 \
|
-p 8700:8700 \
|
||||||
-p 8800:8800 \
|
-p 8800:8800 \
|
||||||
|
|||||||
Reference in New Issue
Block a user