diff --git a/kontor-gin/Containerfile b/kontor-gin/Containerfile index 65160b3..0eadfc6 100644 --- a/kontor-gin/Containerfile +++ b/kontor-gin/Containerfile @@ -10,7 +10,7 @@ RUN go mod download # Copy the source code COPY . . # 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 ---------- FROM alpine:latest @@ -19,9 +19,10 @@ WORKDIR /app # Install runtime dependencies you actually need RUN apk add --no-cache ca-certificates tzdata curl # Copy the binary and set ownership -COPY --from=builder /app/kontor-gin /app/kontor-gin -COPY --from=builder /app/templates /app/templates -COPY --from=builder /app/assets /app/assets -ENV GIN_MODE=release +COPY --from=builder /app/kontor /app/kontor +#COPY --from=builder /app/kontor-gin /app/kontor-gin +#COPY --from=builder /app/templates /app/templates +#COPY --from=builder /app/assets /app/assets +#ENV GIN_MODE=release # Set the entrypoint command -ENTRYPOINT ["/app/kontor-gin"] +ENTRYPOINT ["/app/kontor"] diff --git a/kontor-gin/cmd/kontor-gin/main.go b/kontor-gin/cmd/kontor-gin/main.go deleted file mode 100644 index 03a5fc3..0000000 --- a/kontor-gin/cmd/kontor-gin/main.go +++ /dev/null @@ -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") -} diff --git a/kontor-gin/cmd/kontor/main.go b/kontor-gin/cmd/kontor/main.go index 6e2a57c..fb25c13 100644 --- a/kontor-gin/cmd/kontor/main.go +++ b/kontor-gin/cmd/kontor/main.go @@ -4,11 +4,8 @@ import ( "context" "fmt" "kontor-api-gin/internal/config" - "kontor-api-gin/internal/globals" "kontor-api-gin/internal/handlers" - "kontor-api-gin/internal/repository" "kontor-api-gin/internal/router" - "kontor-api-gin/internal/service" "log" "log/slog" "net/http" @@ -25,7 +22,7 @@ import ( func main() { slog.Info("Kontor started") - if err := globals.InitConfig(); err != nil { + if err := config.InitConfig(); err != nil { log.Fatalf("Failed to initialize config: %v", err) } @@ -46,11 +43,6 @@ func main() { 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 // Production mode disables debug output if viper.GetString("gin.mode") == "release" { @@ -58,11 +50,12 @@ func main() { } r := router.New( - &handlers.ComicHandler{Service: comicService}, - &handlers.AuthHandler{Service: authService}, - []byte(viper.GetString("api_secret")), + handlers.NewAdminHandler(db, []byte(viper.GetString("api_secret"))), + handlers.NewComicsHandler(db), + 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{ Addr: ":" + strconv.Itoa(viper.GetInt("port")), diff --git a/kontor-gin/go.mod b/kontor-gin/go.mod index 0232096..3676a63 100644 --- a/kontor-gin/go.mod +++ b/kontor-gin/go.mod @@ -4,9 +4,9 @@ go 1.26.8 require ( 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-gonic/gin v1.10.1 + github.com/gin-gonic/gin v1.12.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/uuid v1.6.0 github.com/spf13/cobra v1.10.2 @@ -27,9 +27,10 @@ require ( github.com/gin-contrib/sse v1.1.2 // indirect github.com/go-playground/locales v0.14.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/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/securecookie v1.1.2 // 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/reflect2 v1.0.2 // 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/spf13/afero v1.15.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/twitchyliquid64/golang-asm v0.15.1 // 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 golang.org/x/arch v0.31.0 // indirect golang.org/x/net v0.59.0 // indirect diff --git a/kontor-gin/go.sum b/kontor-gin/go.sum index 88fa3a7..6df00a7 100644 --- a/kontor-gin/go.sum +++ b/kontor-gin/go.sum @@ -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/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.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/go.mod h1:PvNXQVXcVOAaaiJR84LV1/xlQHIaXi9ygEXyBkmjdkY= 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-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.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/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 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/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.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/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/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/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= 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/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 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/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 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/ugorji/go/codec v1.3.2 h1:zkEASHHyEClGeURfgNT9PJZVfAbs9oEX9QXggwWNJbc= 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.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= diff --git a/kontor-gin/internal/cmd/check.go b/kontor-gin/internal/cmd/check.go index f09c0d2..dc29356 100644 --- a/kontor-gin/internal/cmd/check.go +++ b/kontor-gin/internal/cmd/check.go @@ -1,6 +1,7 @@ package cmd import ( + "kontor-api-gin/internal/models" "log/slog" "github.com/spf13/cobra" @@ -26,7 +27,7 @@ var checkCmd = &cobra.Command{ slog.Info("Verbosity level", "level", verbose) var login LoginResponse client := resty.New() - res, err := client.R(). + _, err := client.R(). SetBody(Login{ Email: "thomas.peetz@thpeetz.de", Password: "admin", @@ -38,14 +39,23 @@ var checkCmd = &cobra.Command{ slog.Info("Health", "error", err.Error()) } 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). 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", res) + // slog.Info("comics", "res", comics) + defer client.Close() slog.Info("kontor.check_kontor.check_duplicate_links") diff --git a/kontor-gin/internal/cmd/export.go b/kontor-gin/internal/cmd/export.go index 0f1682e..5cd5d91 100644 --- a/kontor-gin/internal/cmd/export.go +++ b/kontor-gin/internal/cmd/export.go @@ -1,9 +1,13 @@ package cmd import ( + "encoding/json" + "kontor-api-gin/internal/models" "log/slog" + "os" "github.com/spf13/cobra" + "resty.dev/v3" ) var exportCmd = &cobra.Command{ @@ -14,6 +18,106 @@ var exportCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { slog.Info("export kontor") 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") }, } diff --git a/kontor-gin/internal/config/config.go b/kontor-gin/internal/config/config.go index fb37f96..61b02cf 100644 --- a/kontor-gin/internal/config/config.go +++ b/kontor-gin/internal/config/config.go @@ -9,6 +9,14 @@ import ( ) 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(".") diff --git a/kontor-gin/internal/globals/config.go b/kontor-gin/internal/globals/config.go deleted file mode 100644 index 866d808..0000000 --- a/kontor-gin/internal/globals/config.go +++ /dev/null @@ -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 -} diff --git a/kontor-gin/internal/globals/globals.go b/kontor-gin/internal/globals/globals.go index 010100d..a4b6795 100644 --- a/kontor-gin/internal/globals/globals.go +++ b/kontor-gin/internal/globals/globals.go @@ -5,7 +5,3 @@ var Secret = []byte("secret") const UserKey = "user" const Version = "0.4.0" - -const LoginUrl = "/login" - -const LogoutUrl = "/auth/logout" diff --git a/kontor-gin/internal/handlers/admin.go b/kontor-gin/internal/handlers/admin.go new file mode 100644 index 0000000..b405db2 --- /dev/null +++ b/kontor-gin/internal/handlers/admin.go @@ -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 +} diff --git a/kontor-gin/internal/handlers/auth.go b/kontor-gin/internal/handlers/auth.go index 2e8bd00..fcbe460 100644 --- a/kontor-gin/internal/handlers/auth.go +++ b/kontor-gin/internal/handlers/auth.go @@ -1,23 +1,128 @@ package handlers import ( + "kontor-api-gin/internal/globals" "kontor-api-gin/internal/helpers" + "kontor-api-gin/internal/models" "kontor-api-gin/internal/service" "net/http" + "github.com/gin-contrib/sessions" "github.com/gin-contrib/slog" "github.com/gin-gonic/gin" ) type AuthHandler struct { Service *service.AuthService + Secret []byte } 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) if err != nil { logger.Info("Login", "GenerateToken error", err.Error()) } 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, "/") +} diff --git a/kontor-gin/internal/handlers/comic.go b/kontor-gin/internal/handlers/comic.go index 2585011..9972be2 100644 --- a/kontor-gin/internal/handlers/comic.go +++ b/kontor-gin/internal/handlers/comic.go @@ -1,12 +1,37 @@ 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 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 { Service *service.ComicService } @@ -17,5 +42,23 @@ func (handler *ComicHandler) List(c *gin.Context) { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 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, + }) } diff --git a/kontor-gin/pkg/controllers/handlers.go b/kontor-gin/internal/handlers/kontor.go similarity index 60% rename from kontor-gin/pkg/controllers/handlers.go rename to kontor-gin/internal/handlers/kontor.go index eef3a8a..22b1a07 100644 --- a/kontor-gin/pkg/controllers/handlers.go +++ b/kontor-gin/internal/handlers/kontor.go @@ -1,15 +1,25 @@ -package controllers +package handlers import ( - "kontor-api-gin/pkg/globals" + "kontor-api-gin/internal/globals" "net/http" + "time" "github.com/gin-contrib/sessions" "github.com/gin-contrib/slog" "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) user := session.Get(globals.UserKey) logger := slog.Get(c) @@ -18,8 +28,7 @@ func IndexGetHandler(c *gin.Context) { "title": "Kontor Gin", "version": "0.4.0", "message": "This is an index page...", - "login": globals.LoginUrl, - "logout": globals.LogoutUrl, "user": user, }) + } diff --git a/kontor-gin/internal/handlers/media.go b/kontor-gin/internal/handlers/media.go new file mode 100644 index 0000000..af53b37 --- /dev/null +++ b/kontor-gin/internal/handlers/media.go @@ -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 +} diff --git a/kontor-gin/internal/handlers/media_actor.go b/kontor-gin/internal/handlers/media_actor.go new file mode 100644 index 0000000..c970024 --- /dev/null +++ b/kontor-gin/internal/handlers/media_actor.go @@ -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, + }) +} diff --git a/kontor-gin/internal/handlers/media_file.go b/kontor-gin/internal/handlers/media_file.go new file mode 100644 index 0000000..5c0a9c9 --- /dev/null +++ b/kontor-gin/internal/handlers/media_file.go @@ -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, + }) +} diff --git a/kontor-gin/internal/handlers/media_lofi.go b/kontor-gin/internal/handlers/media_lofi.go new file mode 100644 index 0000000..ef9efbd --- /dev/null +++ b/kontor-gin/internal/handlers/media_lofi.go @@ -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, + }) +} diff --git a/kontor-gin/internal/handlers/permission.go b/kontor-gin/internal/handlers/permission.go new file mode 100644 index 0000000..eff4dfe --- /dev/null +++ b/kontor-gin/internal/handlers/permission.go @@ -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) +} diff --git a/kontor-gin/internal/handlers/player.go b/kontor-gin/internal/handlers/player.go new file mode 100644 index 0000000..67ff21f --- /dev/null +++ b/kontor-gin/internal/handlers/player.go @@ -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) +} diff --git a/kontor-gin/internal/handlers/position.go b/kontor-gin/internal/handlers/position.go new file mode 100644 index 0000000..e67f7d5 --- /dev/null +++ b/kontor-gin/internal/handlers/position.go @@ -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) +} diff --git a/kontor-gin/internal/handlers/publisher.go b/kontor-gin/internal/handlers/publisher.go new file mode 100644 index 0000000..d84d2d3 --- /dev/null +++ b/kontor-gin/internal/handlers/publisher.go @@ -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) +} diff --git a/kontor-gin/internal/handlers/sport.go b/kontor-gin/internal/handlers/sport.go new file mode 100644 index 0000000..c30a3d6 --- /dev/null +++ b/kontor-gin/internal/handlers/sport.go @@ -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) +} diff --git a/kontor-gin/internal/handlers/team.go b/kontor-gin/internal/handlers/team.go new file mode 100644 index 0000000..9b4471f --- /dev/null +++ b/kontor-gin/internal/handlers/team.go @@ -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) +} diff --git a/kontor-gin/internal/handlers/tysc.go b/kontor-gin/internal/handlers/tysc.go new file mode 100644 index 0000000..f884e2c --- /dev/null +++ b/kontor-gin/internal/handlers/tysc.go @@ -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 +} diff --git a/kontor-gin/internal/handlers/webapp.go b/kontor-gin/internal/handlers/webapp.go new file mode 100644 index 0000000..526bd79 --- /dev/null +++ b/kontor-gin/internal/handlers/webapp.go @@ -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 +} diff --git a/kontor-gin/internal/helpers/auth.go b/kontor-gin/internal/helpers/auth.go index f2c1a4d..7c474cf 100644 --- a/kontor-gin/internal/helpers/auth.go +++ b/kontor-gin/internal/helpers/auth.go @@ -1,6 +1,8 @@ package helpers -import "strings" +import ( + "strings" +) func CheckUserPass(username, password string) bool { return true diff --git a/kontor-gin/internal/middleware/auth.go b/kontor-gin/internal/middleware/auth.go new file mode 100644 index 0000000..3095504 --- /dev/null +++ b/kontor-gin/internal/middleware/auth.go @@ -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() + } +} diff --git a/kontor-gin/internal/middleware/request_id.go b/kontor-gin/internal/middleware/request_id.go index ef7e5a3..0429547 100644 --- a/kontor-gin/internal/middleware/request_id.go +++ b/kontor-gin/internal/middleware/request_id.go @@ -1,16 +1,23 @@ package middleware import ( + "slices" + + "github.com/gin-contrib/slog" "github.com/gin-gonic/gin" "github.com/google/uuid" ) -func RequestID() gin.HandlerFunc { +func RequestID(skipPaths []string) gin.HandlerFunc { return func(c *gin.Context) { + logger := slog.Get(c) id := c.GetHeader("X-Request-ID") if id == "" { 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.Writer.Header().Set("X-Request-ID", id) c.Next() diff --git a/kontor-gin/internal/models/comics/artist.go b/kontor-gin/internal/models/artist.go similarity index 75% rename from kontor-gin/internal/models/comics/artist.go rename to kontor-gin/internal/models/artist.go index a533ca1..b175e12 100644 --- a/kontor-gin/internal/models/comics/artist.go +++ b/kontor-gin/internal/models/artist.go @@ -1,9 +1,9 @@ -package comics +package models import "time" 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"` UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"` DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"` @@ -17,5 +17,6 @@ func (artist *Artist) TableName() string { } type CreateArtistDTO struct { - Name string `json:"name" binding:"required"` + Name string `json:"name" binding:"required"` + WebLink string `json:"weblink" binding:"required"` } diff --git a/kontor-gin/internal/models/assignment.go b/kontor-gin/internal/models/assignment.go new file mode 100644 index 0000000..3f81f02 --- /dev/null +++ b/kontor-gin/internal/models/assignment.go @@ -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"` +} diff --git a/kontor-gin/internal/models/card.go b/kontor-gin/internal/models/card.go new file mode 100644 index 0000000..124cd8d --- /dev/null +++ b/kontor-gin/internal/models/card.go @@ -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 +} diff --git a/kontor-gin/internal/models/cardset.go b/kontor-gin/internal/models/cardset.go new file mode 100644 index 0000000..cc890f9 --- /dev/null +++ b/kontor-gin/internal/models/cardset.go @@ -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 +} diff --git a/kontor-gin/internal/models/comics/comic.go b/kontor-gin/internal/models/comic.go similarity index 60% rename from kontor-gin/internal/models/comics/comic.go rename to kontor-gin/internal/models/comic.go index c004766..6aa5621 100644 --- a/kontor-gin/internal/models/comics/comic.go +++ b/kontor-gin/internal/models/comic.go @@ -1,11 +1,11 @@ -package comics +package models import ( "time" ) 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"` UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_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"` WebLink string `gorm:"column:weblink" json:"weblink"` PublisherID *string `gorm:"column:publisher_id" json:"publisher_id"` + Publisher *Publisher `gorm:"foreignKey:PublisherID"` Issues []Issue `gorm:"foreignKey:ComicID"` StoryArcs []StoryArc `gorm:"foreignKey:ComicID"` TradePaperbacks []TradePaperback `gorm:"foreignKey:ComicID"` @@ -26,6 +27,38 @@ func (comic *Comic) TableName() string { 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 { Title string `json:"title" binding:"required"` } diff --git a/kontor-gin/internal/models/comics/comicwork.go b/kontor-gin/internal/models/comicwork.go similarity index 98% rename from kontor-gin/internal/models/comics/comicwork.go rename to kontor-gin/internal/models/comicwork.go index 1e557c7..f17c65e 100644 --- a/kontor-gin/internal/models/comics/comicwork.go +++ b/kontor-gin/internal/models/comicwork.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/models/comics/issue.go b/kontor-gin/internal/models/issue.go similarity index 98% rename from kontor-gin/internal/models/comics/issue.go rename to kontor-gin/internal/models/issue.go index b61e1a9..bca7ae1 100644 --- a/kontor-gin/internal/models/comics/issue.go +++ b/kontor-gin/internal/models/issue.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/models/comics/issuework.go b/kontor-gin/internal/models/issuework.go similarity index 98% rename from kontor-gin/internal/models/comics/issuework.go rename to kontor-gin/internal/models/issuework.go index 5da4231..2bd6fa3 100644 --- a/kontor-gin/internal/models/comics/issuework.go +++ b/kontor-gin/internal/models/issuework.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/models/media_actor.go b/kontor-gin/internal/models/media_actor.go new file mode 100644 index 0000000..403ce3d --- /dev/null +++ b/kontor-gin/internal/models/media_actor.go @@ -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 +} diff --git a/kontor-gin/internal/models/media_actor_file.go b/kontor-gin/internal/models/media_actor_file.go new file mode 100644 index 0000000..8d6d381 --- /dev/null +++ b/kontor-gin/internal/models/media_actor_file.go @@ -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 +} diff --git a/kontor-gin/internal/models/media_article.go b/kontor-gin/internal/models/media_article.go new file mode 100644 index 0000000..68dbe8d --- /dev/null +++ b/kontor-gin/internal/models/media_article.go @@ -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 +} diff --git a/kontor-gin/internal/models/media_file.go b/kontor-gin/internal/models/media_file.go new file mode 100644 index 0000000..cdb6e22 --- /dev/null +++ b/kontor-gin/internal/models/media_file.go @@ -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 +} diff --git a/kontor-gin/internal/models/media_lofi.go b/kontor-gin/internal/models/media_lofi.go new file mode 100644 index 0000000..c2bedb2 --- /dev/null +++ b/kontor-gin/internal/models/media_lofi.go @@ -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 +} diff --git a/kontor-gin/internal/models/media_video.go b/kontor-gin/internal/models/media_video.go new file mode 100644 index 0000000..9cd9d47 --- /dev/null +++ b/kontor-gin/internal/models/media_video.go @@ -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 +} diff --git a/kontor-gin/internal/models/permission.go b/kontor-gin/internal/models/permission.go new file mode 100644 index 0000000..2d04a45 --- /dev/null +++ b/kontor-gin/internal/models/permission.go @@ -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"` +} diff --git a/kontor-gin/internal/models/player.go b/kontor-gin/internal/models/player.go new file mode 100644 index 0000000..49b1201 --- /dev/null +++ b/kontor-gin/internal/models/player.go @@ -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 +} diff --git a/kontor-gin/internal/models/position.go b/kontor-gin/internal/models/position.go new file mode 100644 index 0000000..6754f9d --- /dev/null +++ b/kontor-gin/internal/models/position.go @@ -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 +} diff --git a/kontor-gin/internal/models/profile.go b/kontor-gin/internal/models/profile.go new file mode 100644 index 0000000..a5747fd --- /dev/null +++ b/kontor-gin/internal/models/profile.go @@ -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"` +} diff --git a/kontor-gin/internal/models/comics/publisher.go b/kontor-gin/internal/models/publisher.go similarity index 53% rename from kontor-gin/internal/models/comics/publisher.go rename to kontor-gin/internal/models/publisher.go index d917d10..1e0a26c 100644 --- a/kontor-gin/internal/models/comics/publisher.go +++ b/kontor-gin/internal/models/publisher.go @@ -1,4 +1,4 @@ -package comics +package models import "time" @@ -20,6 +20,34 @@ func (publisher *Publisher) TableName() string { 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 { Name string `json:"name" binding:"required"` WebLink string `json:"weblink" binding:"required"` diff --git a/kontor-gin/internal/models/rooster.go b/kontor-gin/internal/models/rooster.go new file mode 100644 index 0000000..2a37cf1 --- /dev/null +++ b/kontor-gin/internal/models/rooster.go @@ -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 +} diff --git a/kontor-gin/internal/models/sport.go b/kontor-gin/internal/models/sport.go new file mode 100644 index 0000000..bf241bd --- /dev/null +++ b/kontor-gin/internal/models/sport.go @@ -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"` +} diff --git a/kontor-gin/internal/models/comics/storyarc.go b/kontor-gin/internal/models/storyarc.go similarity index 98% rename from kontor-gin/internal/models/comics/storyarc.go rename to kontor-gin/internal/models/storyarc.go index 44edb94..57c9f0e 100644 --- a/kontor-gin/internal/models/comics/storyarc.go +++ b/kontor-gin/internal/models/storyarc.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/models/team.go b/kontor-gin/internal/models/team.go new file mode 100644 index 0000000..47a628e --- /dev/null +++ b/kontor-gin/internal/models/team.go @@ -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 +} diff --git a/kontor-gin/internal/models/token.go b/kontor-gin/internal/models/token.go new file mode 100644 index 0000000..fd4da28 --- /dev/null +++ b/kontor-gin/internal/models/token.go @@ -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"` +} diff --git a/kontor-gin/internal/models/comics/tradepaperback.go b/kontor-gin/internal/models/tradepaperback.go similarity index 98% rename from kontor-gin/internal/models/comics/tradepaperback.go rename to kontor-gin/internal/models/tradepaperback.go index 5b58cc8..4126fb1 100644 --- a/kontor-gin/internal/models/comics/tradepaperback.go +++ b/kontor-gin/internal/models/tradepaperback.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/models/vendor.go b/kontor-gin/internal/models/vendor.go new file mode 100644 index 0000000..6e39f4b --- /dev/null +++ b/kontor-gin/internal/models/vendor.go @@ -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 +} diff --git a/kontor-gin/internal/models/comics/volume.go b/kontor-gin/internal/models/volume.go similarity index 97% rename from kontor-gin/internal/models/comics/volume.go rename to kontor-gin/internal/models/volume.go index 1e8960f..46b6607 100644 --- a/kontor-gin/internal/models/comics/volume.go +++ b/kontor-gin/internal/models/volume.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/models/comics/worktype.go b/kontor-gin/internal/models/worktype.go similarity index 97% rename from kontor-gin/internal/models/comics/worktype.go rename to kontor-gin/internal/models/worktype.go index 66db81c..63b3924 100644 --- a/kontor-gin/internal/models/comics/worktype.go +++ b/kontor-gin/internal/models/worktype.go @@ -1,4 +1,4 @@ -package comics +package models import "time" diff --git a/kontor-gin/internal/repository/comic.go b/kontor-gin/internal/repository/comic.go index 986983a..7220012 100644 --- a/kontor-gin/internal/repository/comic.go +++ b/kontor-gin/internal/repository/comic.go @@ -2,7 +2,7 @@ package repository import ( "context" - "kontor-api-gin/internal/models/comics" + "kontor-api-gin/internal/models" "log/slog" "gorm.io/gorm" @@ -17,11 +17,11 @@ func NewComicRepository(db *gorm.DB) *ComicRepository { return repo } -func (repository *ComicRepository) List(context context.Context) ([]comics.Comic, error) { - var comics []comics.Comic +func (repository *ComicRepository) FindAll(context context.Context) ([]models.Comic, error) { + var comics []models.Comic result := repository.db.Find(&comics) - slog.Info("ComicRepository#List", "count", result.RowsAffected) + slog.Info("ComicRepository#FindAll", "count", result.RowsAffected) return comics, nil } diff --git a/kontor-gin/internal/repository/media_actor.go b/kontor-gin/internal/repository/media_actor.go new file mode 100644 index 0000000..dd1f86a --- /dev/null +++ b/kontor-gin/internal/repository/media_actor.go @@ -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 +} diff --git a/kontor-gin/internal/repository/media_file.go b/kontor-gin/internal/repository/media_file.go new file mode 100644 index 0000000..58fc111 --- /dev/null +++ b/kontor-gin/internal/repository/media_file.go @@ -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 +} diff --git a/kontor-gin/internal/repository/media_lofi.go b/kontor-gin/internal/repository/media_lofi.go new file mode 100644 index 0000000..90ffc7c --- /dev/null +++ b/kontor-gin/internal/repository/media_lofi.go @@ -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 +} diff --git a/kontor-gin/internal/repository/permission.go b/kontor-gin/internal/repository/permission.go new file mode 100644 index 0000000..b3e210e --- /dev/null +++ b/kontor-gin/internal/repository/permission.go @@ -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 +} diff --git a/kontor-gin/internal/repository/player.go b/kontor-gin/internal/repository/player.go new file mode 100644 index 0000000..8454a7c --- /dev/null +++ b/kontor-gin/internal/repository/player.go @@ -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 +} diff --git a/kontor-gin/internal/repository/position.go b/kontor-gin/internal/repository/position.go new file mode 100644 index 0000000..91bbbfc --- /dev/null +++ b/kontor-gin/internal/repository/position.go @@ -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 +} diff --git a/kontor-gin/internal/repository/profile.go b/kontor-gin/internal/repository/profile.go index 14d8e7f..715c3ca 100644 --- a/kontor-gin/internal/repository/profile.go +++ b/kontor-gin/internal/repository/profile.go @@ -1,6 +1,10 @@ package repository import ( + "context" + "kontor-api-gin/internal/models" + "log/slog" + "gorm.io/gorm" ) @@ -12,3 +16,23 @@ func NewProfileRepository(db *gorm.DB) *ProfileRepository { repository := &ProfileRepository{db: db} 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 +} diff --git a/kontor-gin/internal/repository/publisher.go b/kontor-gin/internal/repository/publisher.go new file mode 100644 index 0000000..5102939 --- /dev/null +++ b/kontor-gin/internal/repository/publisher.go @@ -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 +} diff --git a/kontor-gin/internal/repository/sport.go b/kontor-gin/internal/repository/sport.go new file mode 100644 index 0000000..8b8d613 --- /dev/null +++ b/kontor-gin/internal/repository/sport.go @@ -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 +} diff --git a/kontor-gin/internal/repository/team.go b/kontor-gin/internal/repository/team.go new file mode 100644 index 0000000..b495166 --- /dev/null +++ b/kontor-gin/internal/repository/team.go @@ -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 +} diff --git a/kontor-gin/internal/router/router.go b/kontor-gin/internal/router/router.go index a1be249..00c425c 100644 --- a/kontor-gin/internal/router/router.go +++ b/kontor-gin/internal/router/router.go @@ -3,6 +3,7 @@ package router import ( "html/template" "kontor-api-gin/assets" + "kontor-api-gin/internal/globals" "kontor-api-gin/internal/handlers" "kontor-api-gin/internal/middleware" "kontor-api-gin/templates" @@ -11,11 +12,13 @@ import ( "log/slog" "github.com/gin-contrib/cors" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" gin_slog "github.com/gin-contrib/slog" "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.Use(gin.Recovery()) router.Use(gin_slog.SetLogger( @@ -25,25 +28,70 @@ func New(comics *handlers.ComicHandler, auth *handlers.AuthHandler, secret []byt gin_slog.WithServerErrorLevel(slog.LevelInfo), )) router.Use(cors.New(cors.Config{ - AllowOrigins: []string{"https://app.example.com"}, - AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"}, - AllowHeaders: []string{"Authorization", "Content-Type"}, + AllowOrigins: []string{"https://app.example.com"}, + AllowMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"}, + 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")) router.SetHTMLTemplate(templ) 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.POST("/login", auth.Login) + api.POST("/login", admin.AuthHandler.Login) v1 := api.Group("/v1") { secured := v1.Group("") - secured.Use(middleware.JWT(secret)) - secured.GET("comics/comics", comics.List) + secured.Use(middleware.JWT(admin.Secret)) + 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 } diff --git a/kontor-gin/internal/service/auth.go b/kontor-gin/internal/service/auth.go index e7b651b..7b00381 100644 --- a/kontor-gin/internal/service/auth.go +++ b/kontor-gin/internal/service/auth.go @@ -1,6 +1,11 @@ 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 { repository *repository.ProfileRepository @@ -10,3 +15,33 @@ func NewAuthService(repository *repository.ProfileRepository, secret []byte) *Au service := &AuthService{repository: repository} 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 + +} diff --git a/kontor-gin/internal/service/comic.go b/kontor-gin/internal/service/comic.go index d350521..b6edcd3 100644 --- a/kontor-gin/internal/service/comic.go +++ b/kontor-gin/internal/service/comic.go @@ -2,7 +2,7 @@ package service import ( "context" - "kontor-api-gin/internal/models/comics" + "kontor-api-gin/internal/models" "kontor-api-gin/internal/repository" "log/slog" ) @@ -16,7 +16,7 @@ func NewComicService(repo *repository.ComicRepository) *ComicService { 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") - return service.repository.List(context) + return service.repository.FindAll(context) } diff --git a/kontor-gin/internal/service/media_actor.go b/kontor-gin/internal/service/media_actor.go new file mode 100644 index 0000000..dd3717d --- /dev/null +++ b/kontor-gin/internal/service/media_actor.go @@ -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) +} diff --git a/kontor-gin/internal/service/media_file.go b/kontor-gin/internal/service/media_file.go new file mode 100644 index 0000000..37c8cd3 --- /dev/null +++ b/kontor-gin/internal/service/media_file.go @@ -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) +} diff --git a/kontor-gin/internal/service/media_lofi.go b/kontor-gin/internal/service/media_lofi.go new file mode 100644 index 0000000..e5b35c0 --- /dev/null +++ b/kontor-gin/internal/service/media_lofi.go @@ -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) +} diff --git a/kontor-gin/internal/service/permission.go b/kontor-gin/internal/service/permission.go new file mode 100644 index 0000000..9b98102 --- /dev/null +++ b/kontor-gin/internal/service/permission.go @@ -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) + +} diff --git a/kontor-gin/internal/service/player.go b/kontor-gin/internal/service/player.go new file mode 100644 index 0000000..1e7bebb --- /dev/null +++ b/kontor-gin/internal/service/player.go @@ -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) +} diff --git a/kontor-gin/internal/service/position.go b/kontor-gin/internal/service/position.go new file mode 100644 index 0000000..0250767 --- /dev/null +++ b/kontor-gin/internal/service/position.go @@ -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) +} diff --git a/kontor-gin/internal/service/publisher.go b/kontor-gin/internal/service/publisher.go new file mode 100644 index 0000000..2e33815 --- /dev/null +++ b/kontor-gin/internal/service/publisher.go @@ -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) +} diff --git a/kontor-gin/internal/service/sport.go b/kontor-gin/internal/service/sport.go new file mode 100644 index 0000000..b91653e --- /dev/null +++ b/kontor-gin/internal/service/sport.go @@ -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) +} diff --git a/kontor-gin/internal/service/team.go b/kontor-gin/internal/service/team.go new file mode 100644 index 0000000..0fb9917 --- /dev/null +++ b/kontor-gin/internal/service/team.go @@ -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) +} diff --git a/kontor-gin/pkg/controllers/auth.go b/kontor-gin/pkg/controllers/auth.go deleted file mode 100644 index 2504cbe..0000000 --- a/kontor-gin/pkg/controllers/auth.go +++ /dev/null @@ -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, "/") -} diff --git a/kontor-gin/pkg/controllers/comic.go b/kontor-gin/pkg/controllers/comic.go deleted file mode 100644 index 05eb619..0000000 --- a/kontor-gin/pkg/controllers/comic.go +++ /dev/null @@ -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, - }) - -} diff --git a/kontor-gin/pkg/controllers/comic_api.go b/kontor-gin/pkg/controllers/comic_api.go deleted file mode 100644 index b38e30f..0000000 --- a/kontor-gin/pkg/controllers/comic_api.go +++ /dev/null @@ -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) -} diff --git a/kontor-gin/pkg/controllers/health.go b/kontor-gin/pkg/controllers/health.go deleted file mode 100644 index 98e5b0b..0000000 --- a/kontor-gin/pkg/controllers/health.go +++ /dev/null @@ -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), - }) -} diff --git a/kontor-gin/pkg/controllers/media.go b/kontor-gin/pkg/controllers/media.go deleted file mode 100644 index 44fc647..0000000 --- a/kontor-gin/pkg/controllers/media.go +++ /dev/null @@ -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, - }) -} diff --git a/kontor-gin/pkg/middleware/cors.go b/kontor-gin/pkg/middleware/cors.go deleted file mode 100644 index 4c8a238..0000000 --- a/kontor-gin/pkg/middleware/cors.go +++ /dev/null @@ -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() -} diff --git a/kontor-gin/pkg/middleware/middlewares.go b/kontor-gin/pkg/middleware/middlewares.go deleted file mode 100644 index ed444a1..0000000 --- a/kontor-gin/pkg/middleware/middlewares.go +++ /dev/null @@ -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() -} diff --git a/kontor-gin/pkg/routes/api.go b/kontor-gin/pkg/routes/api.go deleted file mode 100644 index f03d231..0000000 --- a/kontor-gin/pkg/routes/api.go +++ /dev/null @@ -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 -} diff --git a/kontor-gin/pkg/routes/comic.go b/kontor-gin/pkg/routes/comic.go deleted file mode 100644 index d4c4646..0000000 --- a/kontor-gin/pkg/routes/comic.go +++ /dev/null @@ -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) -} diff --git a/kontor-gin/pkg/routes/media.go b/kontor-gin/pkg/routes/media.go deleted file mode 100644 index 09d81c3..0000000 --- a/kontor-gin/pkg/routes/media.go +++ /dev/null @@ -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) -} diff --git a/kontor-gin/pkg/routes/webapp.go b/kontor-gin/pkg/routes/webapp.go deleted file mode 100644 index 86171ec..0000000 --- a/kontor-gin/pkg/routes/webapp.go +++ /dev/null @@ -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) -} diff --git a/kontor-gin/pkg/schema/admin.go b/kontor-gin/pkg/schema/admin.go deleted file mode 100644 index f65d379..0000000 --- a/kontor-gin/pkg/schema/admin.go +++ /dev/null @@ -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" -} diff --git a/kontor-gin/pkg/schema/base.go b/kontor-gin/pkg/schema/base.go deleted file mode 100644 index f247963..0000000 --- a/kontor-gin/pkg/schema/base.go +++ /dev/null @@ -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 -} diff --git a/kontor-gin/pkg/schema/database.go b/kontor-gin/pkg/schema/database.go deleted file mode 100644 index 8127aef..0000000 --- a/kontor-gin/pkg/schema/database.go +++ /dev/null @@ -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") -} diff --git a/kontor-gin/pkg/schema/media.go b/kontor-gin/pkg/schema/media.go deleted file mode 100644 index 2fb23d0..0000000 --- a/kontor-gin/pkg/schema/media.go +++ /dev/null @@ -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" -} diff --git a/kontor-gin/templates/layouts/navbar.html b/kontor-gin/templates/layouts/navbar.html index 9b28a55..e38ef48 100644 --- a/kontor-gin/templates/layouts/navbar.html +++ b/kontor-gin/templates/layouts/navbar.html @@ -1,32 +1,34 @@ {{ define "navbar" }} -
- -
{{ end }} diff --git a/kontor-gin/templates/pages/comics.html b/kontor-gin/templates/pages/comics.html index 3a59b33..40b5ad4 100644 --- a/kontor-gin/templates/pages/comics.html +++ b/kontor-gin/templates/pages/comics.html @@ -39,12 +39,12 @@ Publisher not set {{ end }} - {{ if .Completed }} - true - {{ else }} - true - {{ end }} - + {{ if .Completed }} + true + {{ else }} + true + {{ end }} + Edit Delete diff --git a/kontor-gin/templates/pages/lofi.html b/kontor-gin/templates/pages/lofi.html index d0f5490..0f0985d 100644 --- a/kontor-gin/templates/pages/lofi.html +++ b/kontor-gin/templates/pages/lofi.html @@ -36,8 +36,8 @@ {{ range .lofis }} {{.Title}} - {{ if .Url }} - {{.Url}} + {{ if .WebLink }} + {{.WebLink}} {{ else }} WebLink not set {{ end }} diff --git a/kontor-gin/templates/pages/mediafiles.html b/kontor-gin/templates/pages/mediafiles.html index 13c51d9..88f1659 100644 --- a/kontor-gin/templates/pages/mediafiles.html +++ b/kontor-gin/templates/pages/mediafiles.html @@ -5,7 +5,76 @@ {{ template "navbar" . }} -

{{ .message }}

+
+
+ + + + + +
+
+
+
+ + + + + + + + + + + + {{ range .mediafiles }} + + + {{ if .WebLink }} + + {{ else }} + + {{ end }} + + + + + + {{ end }} + +
TitleWeblinkReviewDownloadActions
{{.Title}}{{.WebLink}}no link + {{ if .Review }} + true + {{ else }} + true + {{ end }} + + {{ if .ShouldDownload }} + true + {{ else }} + true + {{ end }} + EditDelete
+
+
+ {{ template "footer" . }} + + +
+ {{ template "navbar" . }} +
+
+

{{ .message }}

+

{{ .message }}

+

{{ .message }}

+

{{ .message }}

+
{{ template "footer" . }} diff --git a/service/container/pod-kontor.service b/service/container/pod-kontor.service index e5f208d..78123bf 100644 --- a/service/container/pod-kontor.service +++ b/service/container/pod-kontor.service @@ -8,8 +8,8 @@ Documentation=man:podman-generate-systemd(1) Wants=network-online.target After=network-online.target 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 -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 +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-gin.service kontor-javalin.service kontor-quarkus.service kontor-spring.service kontor-vue.service kontor-postgres.service [Service] Environment=PODMAN_SYSTEMD_UNIT=%n @@ -27,6 +27,7 @@ ExecStartPre=/usr/bin/podman pod create \ -p 8300:8300 \ -p 8400:8400 \ -p 8500:8500 \ + -p 8550:8550 \ -p 8600:8600 \ -p 8700:8700 \ -p 8800:8800 \