21 Commits

Author SHA1 Message Date
tpeetz 914e1214de remove obsolete files
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-09-30 04:15:45 +02:00
tpeetz f912dcb670 add tysc handlers to kontor-gin 2026-09-30 04:12:33 +02:00
tpeetz c848758821 move schema to models
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-28 09:42:31 +00:00
tpeetz 2d6fa7b7ee add rest client
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-27 03:09:22 +02:00
Thomas Peetz f0f1819a1f umstellung auf Service und Repository Verwendung - WIP
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-25 16:57:23 +02:00
Thomas Peetz 131296c644 change kontor-gin templates
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-09-24 16:06:38 +02:00
Thomas Peetz ba83d70764 add reading configs
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-23 23:19:10 +02:00
Thomas Peetz a0ad4e5c26 change kontor-gin for containers
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-09-23 17:09:48 +02:00
Thomas Peetz 6b5167a5c0 add imags
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-22 22:46:35 +02:00
Thomas Peetz 044da5353a add templates for kontor-gin
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-09-22 19:19:51 +02:00
Thomas Peetz f2f4a0aaf6 add templates for kontor-gin
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 6s
2026-09-21 19:55:46 +02:00
tpeetz 652aa3005b copy layout from kontor-api
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-20 22:17:42 +02:00
tpeetz ad09386a7a update kontor-fiber to use Go Fiber v3
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-20 02:08:56 +02:00
Thomas Peetz 8f5a384e89 add subproject kontor-gin
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-18 17:42:50 +02:00
Thomas Peetz c1d913e36b add Python library diskcache
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-17 16:37:02 +02:00
Thomas Peetz 8a5bc7873a change usage of secret
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-09-16 16:57:42 +02:00
Thomas Peetz 0ad1969614 separate podman pod creation in several files
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 8s
2026-09-15 13:42:09 +02:00
Thomas Peetz d80aefe6b2 add publishing of kontor-model
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 5s
2026-08-26 18:33:35 +02:00
Thomas Peetz 652378e7de update kontor-api
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 4s
2026-08-25 17:45:03 +02:00
tpeetz 57b942a9ca update Vaadin to 25.2.6 (#95)
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
Co-authored-by: Thomas Peetz <thomas.peetz@cimt-ag.de>
Reviewed-on: #95
2026-08-25 14:15:18 +00:00
Thomas Peetz bda453a92a change to version 0.4.0-SNAPSHOT
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 3s
2026-08-25 11:11:51 +02:00
297 changed files with 15348 additions and 1776 deletions
+1
View File
@@ -11,3 +11,4 @@ kontor-robyn.bak
kontor-robyn.bak2 kontor-robyn.bak2
kontor-data/.gradle kontor-data/.gradle
kontor-data/build/ kontor-data/build/
/kontor-api/kontor-api.code-workspace
+1 -1
View File
@@ -4,7 +4,7 @@ NEXUS_URL=https://nexus.thpeetz.de
MAVEN_REPO=maven-snapshots MAVEN_REPO=maven-snapshots
GROUP_ID=de.thpeetz GROUP_ID=de.thpeetz
ARTIFACT_ID=kontor-spring ARTIFACT_ID=kontor-spring
VERSION=0.3.0 VERSION=0.4.0
FILE_EXTENSION=jar FILE_EXTENSION=jar
download_url=$(curl -X GET "${NEXUS_URL}/service/rest/v1/search/assets?repository=${MAVEN_REPO}&maven.groupId=${GROUP_ID}&maven.artifactId=${ARTIFACT_ID}&maven.baseVersion=${VERSION}&maven.extension=${FILE_EXTENSION}" -H "accept: application/json" | jq -rc '.items | .[].downloadUrl' | sort | tail -n 1) download_url=$(curl -X GET "${NEXUS_URL}/service/rest/v1/search/assets?repository=${MAVEN_REPO}&maven.groupId=${GROUP_ID}&maven.artifactId=${ARTIFACT_ID}&maven.baseVersion=${VERSION}&maven.extension=${FILE_EXTENSION}" -H "accept: application/json" | jq -rc '.items | .[].downloadUrl' | sort | tail -n 1)
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-angular:$kontorVersion"
buildah build -t kontor-angular:$kontorVersion kontor-angular
-3
View File
@@ -14,9 +14,6 @@ ENV PATH="/root/.local/bin:${PATH}"
WORKDIR /app WORKDIR /app
COPY ./pyproject.toml . COPY ./pyproject.toml .
#RUN --mount=type=bind,source=/home/tpeetz/projects/kontor/kontor-model,target=/container/kontor-model uv add /container/kontor-model
#COPY ../kontor-model/ /container
RUN uv add /container/kontor-model
RUN uv sync RUN uv sync
# ------------------------------- Production Stage ------------------------------ ## # ------------------------------- Production Stage ------------------------------ ##
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-api:$kontorVersion"
buildah build -t kontor-api:$kontorVersion kontor-api
+11 -3
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "kontor-api" name = "kontor-api"
version = "0.1.0" version = "0.4.0"
description = "Add your description here" description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"
@@ -32,5 +32,13 @@ dependencies = [
"kontor-model", "kontor-model",
] ]
[tool.uv.sources] [[tool.uv.index]]
kontor-model = { path = "../kontor-model", editable = true } name = "nexus"
url = "https://nexus.thpeetz.de/repository/pypi-group/simple"
publish-url = "https://nexus.thpeetz.de/repository/pypi-internal/"
default = true
[[tool.uv.index]]
name = "nexus-proxy"
url = "https://nexus.thpeetz.de/repository/pypi-proxy/simple"
+51 -2
View File
@@ -1,11 +1,21 @@
from typing import List from typing import List
from fastapi import APIRouter, HTTPException from fastapi import APIRouter, status, HTTPException
from kontor_model.db.models.media import MediaLofi from kontor_model.db.models.media import MediaLofi
from src.db.session import SessionDep from src.db.session import SessionDep
from kontor_model.schema.media.lofi import MediaLofiResponse, lofi_to_response from src.core.log_conf import logger
from kontor_model.schema.media.lofi import (
MediaLofiModel,
MediaLofiResponse,
lofi_to_response,
lofi_to_model
)
from kontor_model.db.repository.media.lofi import (
import_medialofi,
delete_medialofi
)
router = APIRouter() router = APIRouter()
@@ -40,3 +50,42 @@ def get_lofi(lofi_id: str, db: SessionDep) -> MediaLofiResponse:
raise HTTPException(status_code=404, detail="MediaLofi could not be found") raise HTTPException(status_code=404, detail="MediaLofi could not be found")
response = lofi_to_response(lofi) response = lofi_to_response(lofi)
return response return response
@router.delete("/lofi/{lofi_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_lofi(lofi_id: str, db: SessionDep):
"""
Delete MediaFile by given id.
"""
lofi = db.get(MediaLofi, lofi_id)
if not lofi:
raise HTTPException(status_code=404, detail="MediaLofi could not be found")
logger.info("delete MediaLofi: %s", lofi_id)
delete_medialofi(db=db, lofi_id=lofi.id)
@router.put("/lofi/{lofi_id}", response_model=MediaLofiResponse)
def update_lofi(lofi_id: str, db: SessionDep, info: MediaLofiResponse) -> MediaLofiResponse:
"""
Update MediaLofi with given id and data.
"""
media_lofi = db.get(MediaLofi, lofi_id)
if not media_lofi:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="MediaLofi could not be found")
lofi_to_model(info, media_lofi)
db.add(media_lofi)
db.commit()
media_lofi = db.get(MediaLofi, lofi_id)
if not media_lofi:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="MediaLofi could not be found")
response = lofi_to_response(media_lofi)
return response
@router.post("/lofi", status_code=status.HTTP_201_CREATED)
def add_lofi(new_lofi: MediaLofiModel, db: SessionDep) -> MediaLofiResponse:
logger.info("add medialofi %s", new_lofi)
try:
medialofi: MediaLofi = import_medialofi(db, new_lofi)
except:
raise HTTPException(status_code=409, detail="MediaLofi duplicate")
response = lofi_to_response(medialofi)
return response
+8 -4
View File
@@ -9,17 +9,21 @@ load_dotenv(dotenv_path=env_path)
class Settings: class Settings:
PROJECT_NAME: str = "Kontor" PROJECT_NAME: str = "Kontor"
PROJECT_VERSION: str = "0.3.0" PROJECT_VERSION: str = "0.4.0"
DB_USER: str = os.getenv("DB_USER", "kontor") DB_USER: str = os.getenv("DB_USER", "kontor")
DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor") DB_PASSWORD: str = os.getenv("DB_PASSWORD", "kontor")
DB_SERVER: str = os.getenv("DB_SERVER", "postgres") DB_SERVER: str = os.getenv("DB_SERVER", "postgres")
DB_PORT: int = int(os.getenv("DB_PORT", 5432)) DB_PORT: int = int(os.getenv("DB_PORT", 5432))
DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor") DB_DBNAME: str = os.getenv("DB_DBNAME", "kontor")
DATABASE_URL: str = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}" DATABASE_URL: str = (
SECRET_KEY: str = os.getenv("SECRET_KEY", "J6GOtcwC2NJI1l0VkHu20PacPFGTxpirBxWwynoHjsc=") f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_SERVER}:{DB_PORT}/{DB_DBNAME}"
)
SECRET_KEY: str = os.getenv(
"SECRET_KEY", "J6GOtcwC2NJI1l0VkHu20PacPFGTxpirBxWwynoHjsc="
)
ALGORITHM = "HS256" ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7 # one week in mins ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 * 7 # one week in mins
settings = Settings()
settings = Settings()
+1007 -596
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
# This file was generated by the Gradle 'init' task. # This file was generated by the Gradle 'init' task.
# https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties # https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties
description='Kontor Documentation' description='Kontor Documentation'
version=0.3.0 version=0.4.0-SNAPSHOT
group=de.thpeetz group=de.thpeetz
org.gradle.configuration-cache=true org.gradle.configuration-cache=true
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-echo:$kontorVersion"
buildah build -t kontor-echo:$kontorVersion kontor-echo
+3 -1
View File
@@ -1,5 +1,5 @@
# ---------- Stage 1: Build ---------- # ---------- Stage 1: Build ----------
FROM docker.io/library/golang:1.25-alpine AS builder FROM docker.io/library/golang:1.26-alpine AS builder
# Set the working directory # Set the working directory
WORKDIR /app WORKDIR /app
# Ensure a portable, static-ish binary # Ensure a portable, static-ish binary
@@ -20,5 +20,7 @@ WORKDIR /app
RUN apk add --no-cache ca-certificates tzdata curl RUN apk add --no-cache ca-certificates tzdata curl
# Copy the binary and set ownership # Copy the binary and set ownership
COPY --from=builder /app/kontor /app/kontor COPY --from=builder /app/kontor /app/kontor
COPY --from=builder /app/views /app/views
COPY --from=builder /app/static /app/static
# Set the entrypoint command # Set the entrypoint command
ENTRYPOINT ["/app/kontor"] ENTRYPOINT ["/app/kontor"]
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-fiber:$kontorVersion"
buildah build -t kontor-fiber:$kontorVersion kontor-fiber
+28 -9
View File
@@ -3,11 +3,15 @@ package main
import ( import (
"kontor-api-fiber/pkg/handler" "kontor-api-fiber/pkg/handler"
"kontor-api-fiber/pkg/schema" "kontor-api-fiber/pkg/schema"
"kontor-api-fiber/pkg/web"
"log" "log"
"time"
jwtware "github.com/gofiber/contrib/jwt" jwtware "github.com/gofiber/contrib/v3/jwt"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v2/middleware/logger" "github.com/gofiber/fiber/v3/middleware/logger"
"github.com/gofiber/fiber/v3/middleware/static"
"github.com/gofiber/template/html/v3"
) )
func main() { func main() {
@@ -16,24 +20,39 @@ func main() {
if err := schema.Connect(); err != nil { if err := schema.Connect(); err != nil {
log.Fatal(err) log.Fatal(err)
} }
// Create a new engine
engine := html.New("./views", ".html")
app := fiber.New() app := fiber.New(fiber.Config{
Views: engine,
// app.Use(jwtware.New(jwtware.Config{ ViewsLayout: "layouts/main",
// SigningKey: jwtware.SigningKey{Key: []byte("secret")}, })
// }))
//app.Use(logger.New()) //app.Use(logger.New())
app.Get("/health", handler.GetHealth) app.Get("/health", handler.GetHealth)
app.Post("/login", handler.Login) app.Post("/login", handler.Login)
web.SetupRoutes(app)
api := app.Group("/api", logger.New(), jwtware.New(jwtware.Config{ //api := app.Group("/api/v1")
api := app.Group("/api/v1", logger.New(), jwtware.New(jwtware.Config{
SigningKey: jwtware.SigningKey{Key: []byte("secret")}, SigningKey: jwtware.SigningKey{Key: []byte("secret")},
})) }))
api.Use(logger.New()) api.Use(logger.New())
handler.SetupComicRoutes(api) handler.SetupComicRoutes(api)
handler.SetupMediaRoutes(api) handler.SetupMediaRoutes(api)
app.Get("/*", static.New("./static", static.Config{
Browse: false,
MaxAge: 3600,
CacheDuration: 10 * time.Second,
NotFoundHandler: func(c fiber.Ctx) error {
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
"error": "asset not found",
"path": c.Path(),
})
},
}))
// Listen on port 8900 // Listen on port 8900
app.Listen(":8500") app.Listen(":8500")
+45 -28
View File
@@ -1,42 +1,59 @@
module kontor-api-fiber module kontor-api-fiber
go 1.24.2 go 1.26.0
require (
github.com/gofiber/contrib/jwt v1.1.2
github.com/gofiber/fiber/v3 v3.5.0
github.com/gofiber/template/html/v3 v3.0.9
github.com/golang-jwt/jwt/v5 v5.3.1
github.com/google/uuid v1.6.0
github.com/stretchr/testify v1.12.1
github.com/uptrace/bun v1.2.18
github.com/uptrace/bun/dialect/pgdialect v1.2.18
github.com/uptrace/bun/driver/pgdriver v1.2.18
github.com/uptrace/bun/extra/bundebug v1.2.18
golang.org/x/crypto v0.57.0
)
require ( require (
github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect github.com/andybalholm/brotli v1.2.4 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.19.0 // indirect
github.com/fatih/color v1.18.0 // indirect github.com/go-logr/logr v1.4.4 // indirect
github.com/gofiber/contrib/jwt v1.1.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/gofiber/fiber/v2 v2.52.10 // indirect github.com/gofiber/contrib/v3/jwt v1.2.4 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/gofiber/fiber/v2 v2.52.15 // indirect
github.com/google/uuid v1.6.0 // indirect github.com/gofiber/schema v1.8.7 // indirect
github.com/gofiber/template/v2 v2.1.2 // indirect
github.com/gofiber/utils/v2 v2.5.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/joho/godotenv v1.5.1 // indirect github.com/klauspost/compress v1.20.0 // indirect
github.com/klauspost/compress v1.18.1 // indirect github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.24 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.30 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect github.com/molecule-man/go-brrr v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/philhofer/fwd v1.2.0 // indirect
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/tinylib/msgp v1.6.4 // indirect
github.com/stretchr/testify v1.11.1 // indirect
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect
github.com/uptrace/bun v1.2.16 // indirect
github.com/uptrace/bun/dialect/pgdialect v1.2.16 // indirect
github.com/uptrace/bun/driver/pgdriver v1.2.16 // indirect
github.com/uptrace/bun/extra/bundebug v1.2.16 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.68.0 // indirect github.com/valyala/fasthttp v1.74.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
go.opentelemetry.io/otel v1.38.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/trace v1.38.0 // indirect go.opentelemetry.io/otel v1.46.0 // indirect
golang.org/x/crypto v0.45.0 // indirect go.opentelemetry.io/otel/metric v1.46.0 // indirect
golang.org/x/sys v0.39.0 // indirect go.opentelemetry.io/otel/trace v1.46.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/mod v0.41.0 // indirect
golang.org/x/net v0.59.0 // indirect
golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect
golang.org/x/tools v0.49.0 // indirect
mellium.im/sasl v0.3.2 // indirect mellium.im/sasl v0.3.2 // indirect
) )
+102 -56
View File
@@ -1,98 +1,144 @@
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k= github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k= github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.2.2 h1:HzTuoo2ErYQqf5qvcJInB8uvqSVxRttzkFexPWtnceM=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.2/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= github.com/andybalholm/brotli v1.2.4 h1:649LN6qF+/7JJYNN3Wdu4Dt5PS6eC/yP/Go3Bb0/AHI=
github.com/andybalholm/brotli v1.2.4/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4= github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/fxamacker/cbor/v2 v2.9.3 h1:oQBnFATpNdY8gJHTndDDv5Xl4QqNaz51G5LLEPhng3Q=
github.com/fxamacker/cbor/v2 v2.9.3/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gofiber/contrib/jwt v1.1.2 h1:GmWnOqT4A15EkA8IPXwSpvNUXZR4u5SMj+geBmyLAjs= github.com/gofiber/contrib/jwt v1.1.2 h1:GmWnOqT4A15EkA8IPXwSpvNUXZR4u5SMj+geBmyLAjs=
github.com/gofiber/contrib/jwt v1.1.2/go.mod h1:CpIwrkUQ3Q6IP8y9n3f0wP9bOnSKx39EDp2fBVgMFVk= github.com/gofiber/contrib/jwt v1.1.2/go.mod h1:CpIwrkUQ3Q6IP8y9n3f0wP9bOnSKx39EDp2fBVgMFVk=
github.com/gofiber/fiber v1.14.6 h1:QRUPvPmr8ijQuGo1MgupHBn8E+wW0IKqiOvIZPtV70o= github.com/gofiber/contrib/v3/jwt v1.2.4 h1:0cApE/65Nb+AV49zMjun2+vXE1pCdZWLdg1z3IxmrPI=
github.com/gofiber/fiber v1.14.6/go.mod h1:Yw2ekF1YDPreO9V6TMYjynu94xRxZBdaa8X5HhHsjCM= github.com/gofiber/contrib/v3/jwt v1.2.4/go.mod h1:ARfFxE8uxUeV5hzq9qUaSCBWkpYmGpvAL/XU3NBpkRA=
github.com/gofiber/fiber/v2 v2.52.10 h1:jRHROi2BuNti6NYXmZ6gbNSfT3zj/8c0xy94GOU5elY= github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
github.com/gofiber/fiber/v2 v2.52.10/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/gofiber/utils v0.0.10/go.mod h1:9J5aHFUIjq0XfknT4+hdSMG6/jzfaAgCu4HEbWDeBlo= github.com/gofiber/fiber/v2 v2.52.15 h1:Cov1uKeVPyu9q0jSrN60W+A8XNX+/WK8J7cy5osHLIk=
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= github.com/gofiber/fiber/v2 v2.52.15/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= github.com/gofiber/fiber/v3 v3.5.0 h1:dk7TOUH6DXJGtOLsN2XEG+0ZML7cznzHILTVozbNEK8=
github.com/gofiber/fiber/v3 v3.5.0/go.mod h1:GOVDTW+gjJvfe0iJyVujbQ1Lnx+JUjFySJRI/9/xX/w=
github.com/gofiber/schema v1.8.3 h1:06ZedxIYjngzc0095PYy7uWnFnbRflWFpikvZH61fDc=
github.com/gofiber/schema v1.8.3/go.mod h1:jWnnZdhcW1mHyV+VnfRxKJDPNcepJsTZ9RIWxrr32Ng=
github.com/gofiber/schema v1.8.7 h1:7cSagr2ObiUVFuitCOqjKMqIhV+oVbkanP4Ge/wHsnI=
github.com/gofiber/schema v1.8.7/go.mod h1:fBz4T6uOepH3L+dYlz/yzQ0bFHPnfExkp/B3Qrk2VBI=
github.com/gofiber/template/html/v3 v3.0.9 h1:oVgrQIGSe7DcufnD823KwLsUnIgtCDGhznj1kMfNB2I=
github.com/gofiber/template/html/v3 v3.0.9/go.mod h1:Nk2HJlZYaCd0oVEwQd8v+1M+gmweub6dEAeS07WhL6o=
github.com/gofiber/template/v2 v2.1.2 h1:fZTpavK0Yi1ehJGrL9UXzBrOnowZfPpIZwxfiIftXBs=
github.com/gofiber/template/v2 v2.1.2/go.mod h1:h8vOKQkwFUFRNTvRcIvt/OgVUOVqHsaEviWTOAh2JqQ=
github.com/gofiber/utils/v2 v2.5.2 h1:bX+iACKsCGm2+dW7jvkYSiWIsBaKqFy5slFSxJSIL/s=
github.com/gofiber/utils/v2 v2.5.2/go.mod h1:EaVDjy4JJv0m0lg6x4owJ1GG8j1pMO8XriqCgVns1ZQ=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
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=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA=
github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/mattn/go-runewidth v0.0.30 h1:+KUuiDA4fF0R1p5FeueHefjDm+GIM+kWfFnDjybOPgk=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/mattn/go-runewidth v0.0.30/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8=
github.com/molecule-man/go-brrr v1.0.1 h1:cEjgx8hgNw6UGdhQ94SPDbPkKuRbkUcxBO3IzbGpA/o=
github.com/molecule-man/go-brrr v1.0.1/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
github.com/molecule-man/go-brrr v1.1.0 h1:rLBGSXA393y+5ttCBLkW34CHESop5tahrOFxVv/XDEU=
github.com/molecule-man/go-brrr v1.1.0/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
github.com/molecule-man/go-brrr v1.1.1 h1:KYwusQhjtV3smALnhmafZf4OBrh7vP4p8O47DyUmmuY=
github.com/molecule-man/go-brrr v1.1.1/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/shamaton/msgpack/v3 v3.2.3 h1:0r0aZtrXDFOPpwWJTEOpFq+Ih/JmMLm0pqLN5mSilrw=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/shamaton/msgpack/v3 v3.2.3/go.mod h1:sgBYvEiyz8JR1NC3yGRoPVME9xXovpnh3l/plW1nfRo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ=
github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo=
github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs=
github.com/uptrace/bun v1.2.16 h1:QlObi6ZIK5Ao7kAALnh91HWYNZUBbVwye52fmlQM9kc= github.com/uptrace/bun v1.2.16 h1:QlObi6ZIK5Ao7kAALnh91HWYNZUBbVwye52fmlQM9kc=
github.com/uptrace/bun v1.2.16/go.mod h1:jMoNg2n56ckaawi/O/J92BHaECmrz6IRjuMWqlMaMTM= github.com/uptrace/bun v1.2.16/go.mod h1:jMoNg2n56ckaawi/O/J92BHaECmrz6IRjuMWqlMaMTM=
github.com/uptrace/bun v1.2.18 h1:3HnRcMfS6OBPMG1eSOzlbFJ/X/AyMEJb7rMxE6VQvDU=
github.com/uptrace/bun v1.2.18/go.mod h1:wNltaKJk4JtOt4SG5I5zmA7v0/Mzjh1+/S906Rayd3Y=
github.com/uptrace/bun/dialect/pgdialect v1.2.16 h1:KFNZ0LxAyczKNfK/IJWMyaleO6eI9/Z5tUv3DE1NVL4= github.com/uptrace/bun/dialect/pgdialect v1.2.16 h1:KFNZ0LxAyczKNfK/IJWMyaleO6eI9/Z5tUv3DE1NVL4=
github.com/uptrace/bun/dialect/pgdialect v1.2.16/go.mod h1:IJdMeV4sLfh0LDUZl7TIxLI0LipF1vwTK3hBC7p5qLo= github.com/uptrace/bun/dialect/pgdialect v1.2.16/go.mod h1:IJdMeV4sLfh0LDUZl7TIxLI0LipF1vwTK3hBC7p5qLo=
github.com/uptrace/bun/dialect/pgdialect v1.2.18 h1:IZ6nM2+OYrL8lkEAy7UkSEZvoa3vluTAUlZfPtlRB2k=
github.com/uptrace/bun/dialect/pgdialect v1.2.18/go.mod h1:Tqdf4QP1okrGYpXfodXvCOK6Ob1OOTwSaoAzCgBB3IU=
github.com/uptrace/bun/driver/pgdriver v1.2.16 h1:b1kpXKUxtTSGYow5Vlsb+dKV3z0R7aSAJNfMfKp61ZU= github.com/uptrace/bun/driver/pgdriver v1.2.16 h1:b1kpXKUxtTSGYow5Vlsb+dKV3z0R7aSAJNfMfKp61ZU=
github.com/uptrace/bun/driver/pgdriver v1.2.16/go.mod h1:H6lUZ9CBfp1X5Vq62YGSV7q96/v94ja9AYFjKvdoTk0= github.com/uptrace/bun/driver/pgdriver v1.2.16/go.mod h1:H6lUZ9CBfp1X5Vq62YGSV7q96/v94ja9AYFjKvdoTk0=
github.com/uptrace/bun/driver/pgdriver v1.2.18 h1:Zojuc83ulApocXomBLEcx1DqCZweREafHCjPfyXo88I=
github.com/uptrace/bun/driver/pgdriver v1.2.18/go.mod h1:ZRJcARw93nxbQ5WawTrc5EO+F+GygkcYgDLEnT17CcE=
github.com/uptrace/bun/extra/bundebug v1.2.16 h1:3OXAfHTU4ydu2+4j05oB1BxPx6+ypdWIVzTugl/7zl0= github.com/uptrace/bun/extra/bundebug v1.2.16 h1:3OXAfHTU4ydu2+4j05oB1BxPx6+ypdWIVzTugl/7zl0=
github.com/uptrace/bun/extra/bundebug v1.2.16/go.mod h1:vk6R/1i67/S2RvUI5AH/m3P5e67mOkfDCmmCsAPUumo= github.com/uptrace/bun/extra/bundebug v1.2.16/go.mod h1:vk6R/1i67/S2RvUI5AH/m3P5e67mOkfDCmmCsAPUumo=
github.com/uptrace/bun/extra/bundebug v1.2.18 h1:5cgkqdvhpSHIEONazSytm4RWYFneNtcznaWLt6r8m4M=
github.com/uptrace/bun/extra/bundebug v1.2.18/go.mod h1:M+U9YJVJcmk0RrszCb2Q1oskJiJ0LuC44FxDhZLP1ws=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA= github.com/valyala/fasthttp v1.73.0 h1:ocTOORnBWtJ+P8t/6wAjdkchMzdfHmWx2VD/DPbgZ7s=
github.com/valyala/fasthttp v1.68.0 h1:v12Nx16iepr8r9ySOwqI+5RBJ/DqTxhOy1HrHoDFnok= github.com/valyala/fasthttp v1.73.0/go.mod h1:EtXQDHaR+5P18p8wqDRFpUhxr108Ga9mXvVJXHRrN2k=
github.com/valyala/fasthttp v1.68.0/go.mod h1:5EXiRfYQAoiO/khu4oU9VISC/eVY6JqmSpPJoHCKsz4= github.com/valyala/fasthttp v1.74.0 h1:wMS9fnO2QTALozYx5pId2Vi7ZwU/epUkY8i/KPWCHoU=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/valyala/fasthttp v1.74.0/go.mod h1:3ARmLamUcw7ElxVtC8PXaGzQ6VEuvnetlkrwIklQBSE=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc=
go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE=
go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o=
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c=
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI=
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0=
mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY= mellium.im/sasl v0.3.2/go.mod h1:NKXDi1zkr+BlMHLQjY3ofYuU4KSPFxknb8mfEu6SveY=
+3 -3
View File
@@ -5,12 +5,12 @@ import (
"kontor-api-fiber/pkg/schema" "kontor-api-fiber/pkg/schema"
"kontor-api-fiber/pkg/utils" "kontor-api-fiber/pkg/utils"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v3"
"github.com/golang-jwt/jwt/v5" "github.com/golang-jwt/jwt/v5"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
func Login(c *fiber.Ctx) error { func Login(c fiber.Ctx) error {
user := c.FormValue("user") user := c.FormValue("user")
pass := c.FormValue("pass") pass := c.FormValue("pass")
@@ -39,7 +39,7 @@ func Login(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"token": token}) return c.JSON(fiber.Map{"token": token})
} }
func Restricted(c *fiber.Ctx) error { func Restricted(c fiber.Ctx) error {
user := c.Locals("user").(*jwt.Token) user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims) claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string) name := claims["name"].(string)
+4 -4
View File
@@ -5,7 +5,7 @@ import (
"kontor-api-fiber/pkg/schema" "kontor-api-fiber/pkg/schema"
"log" "log"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v3"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
@@ -16,7 +16,7 @@ func SetupComicRoutes(api fiber.Router) {
comics.Get("/comicworks", GetAllComicWorks) comics.Get("/comicworks", GetAllComicWorks)
} }
func GetAllComics(c *fiber.Ctx) error { func GetAllComics(c fiber.Ctx) error {
var comics []schema.Comic var comics []schema.Comic
var err error var err error
var db *bun.DB var db *bun.DB
@@ -36,7 +36,7 @@ func GetAllComics(c *fiber.Ctx) error {
return c.JSON(comics) return c.JSON(comics)
} }
func GetAllPublishers(c *fiber.Ctx) error { func GetAllPublishers(c fiber.Ctx) error {
var publishers []schema.Publisher var publishers []schema.Publisher
var err error var err error
var db *bun.DB var db *bun.DB
@@ -56,7 +56,7 @@ func GetAllPublishers(c *fiber.Ctx) error {
return c.JSON(publishers) return c.JSON(publishers)
} }
func GetAllComicWorks(c *fiber.Ctx) error { func GetAllComicWorks(c fiber.Ctx) error {
var comic_works []schema.ComicWork var comic_works []schema.ComicWork
var err error var err error
var db *bun.DB var db *bun.DB
+2 -2
View File
@@ -1,8 +1,8 @@
package handler package handler
import "github.com/gofiber/fiber/v2" import "github.com/gofiber/fiber/v3"
func GetHealth(c *fiber.Ctx) error { func GetHealth(c fiber.Ctx) error {
return c.Status(200).JSON(&fiber.Map{ return c.Status(200).JSON(&fiber.Map{
"status": "ok", "status": "ok",
}) })
+3 -3
View File
@@ -8,7 +8,7 @@ import (
"log" "log"
"time" "time"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v3"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/uptrace/bun" "github.com/uptrace/bun"
) )
@@ -19,7 +19,7 @@ func SetupMediaRoutes(api fiber.Router) {
media.Post("/files", AddFile) media.Post("/files", AddFile)
} }
func GetAllFiles(c *fiber.Ctx) error { func GetAllFiles(c fiber.Ctx) error {
var files []schema.MediaFile var files []schema.MediaFile
var err error var err error
var db *bun.DB var db *bun.DB
@@ -38,7 +38,7 @@ func GetAllFiles(c *fiber.Ctx) error {
return c.JSON(files) return c.JSON(files)
} }
func AddFile(c *fiber.Ctx) error { func AddFile(c fiber.Ctx) error {
var err error var err error
var db *bun.DB var db *bun.DB
ctx := context.Background() ctx := context.Background()
+14
View File
@@ -24,6 +24,20 @@ type MediaFile struct {
MediaActorFiles []MediaActorFile `bun:"rel:has-many,join:id=media_file_id"` MediaActorFiles []MediaActorFile `bun:"rel:has-many,join:id=media_file_id"`
} }
type MediaLoFi struct {
bun.BaseModel `bun:"table:media_lofi"`
ID string `bun:"id,pk"`
CreatedAt time.Time `bun:"created_date,nullzero,notnull,default:current_timestamp"`
UpdatedAt time.Time `bun:"last_modified_date,nullzero,notnull,default:current_timestamp"`
Version int `bun:"version,default:0"`
WebLink string `bun:"url,unique:url"`
Review bool `bun:"review"`
ShouldDownload bool `bun:"should_download"`
Title string `bun:"title"`
FileName string `bun:"file_name"`
}
type MediaActor struct { type MediaActor struct {
bun.BaseModel `bun:"table:media_actor"` bun.BaseModel `bun:"table:media_actor"`
+9
View File
@@ -0,0 +1,9 @@
package web
import "github.com/gofiber/fiber/v3"
func Mainpage(c fiber.Ctx) error {
return c.Render("index", fiber.Map{
"Title": "Kontor Fiber",
})
}
+12
View File
@@ -0,0 +1,12 @@
package web
import (
"github.com/gofiber/fiber/v3"
)
func SetupRoutes(app *fiber.App) {
app.Get("/", Mainpage)
app.Get("/comic/comics", Mainpage)
app.Get("/media/files", Mainpage)
}
+172
View File
@@ -0,0 +1,172 @@
* {
box-sizing: border-box;
}
body {
font-family: Arial;
padding: 10px;
background: lightgrey;
}
/* Header/Blog Title */
.header {
padding: 30px;
text-align: center;
background-color: lightblue;
}
.header h1 {
font-size: 50px;
}
/* Style the top navigation bar */
.topnav {
overflow: hidden;
background-color: darkgrey;
}
/* Style the topnav links */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
/* Change color on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
.subnav {
overflow: hidden;
background-color: grey;
}
.subnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center;
padding-top: 10px;
padding-left: 20px;
}
.form-inline label {
margin: 5px 10px 5px 0;
}
.form-inline input {
padding-right: 50px;
margin-right: 10px;
}
.form-inline button {
padding: 10px 20px;
background-color: dodgerblue;
border: 1px solid #ddd;
color: white;
border-radius: 10px;
}
.form-inline button:hover {
background-color: royalblue;
}
.pill-nav a {
display: inline-block;
color: white;
background-color: dodgerblue;
text-align: center;
padding: 10px;
text-decoration: none;
border-radius: 10px;
margin-left: 20px;
}
/* Change the color of links on mouse-over */
.pill-nav a:hover {
background-color: royalblue;
color: white;
}
/* Add a color to the active/current link */
.pill-nav a.active {
background-color: royalblue;
color: white;
}
.maincolumn {
float:left;
width: 100%;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 75%;
}
/* Right column */
.rightcolumn {
float: left;
width: 25%;
background-color: #f1f1f1;
padding-left: 20px;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
background-color: white;
padding: 20px;
margin-top: 20px;
}
/* Clear floats after the columns */
.row::after {
content: "";
display: table;
clear: both;
}
/* Footer */
.footer {
padding: 20px;
text-align: center;
background: #ddd;
margin-top: 20px;
}
/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
.leftcolumn, .rightcolumn {
width: 100%;
padding: 0;
}
}
/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */
@media screen and (max-width: 400px) {
.topnav a {
float: none;
width: 100%;
}
}
+1
View File
@@ -0,0 +1 @@
<h1>{{.Title}}</h1>
+22
View File
@@ -0,0 +1,22 @@
<!doctype html>
<html lang="de-DE">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="/style/main.css" />
<title>{{.Title}}</title>
</head>
<body>
<div class="header">{{template "partials/header" .}}</div>
{{template "partials/navbar" .}}
<div class="content">{{embed}}</div>
<div class="footer">{{template "partials/footer" .}}</div>
</body>
</html>
+1
View File
@@ -0,0 +1 @@
<h2>Footer</h2>
+1
View File
@@ -0,0 +1 @@
<h2>Header</h2>
@@ -0,0 +1,6 @@
<div class="subnav">
<a href="/media/files/">MediaFiles</a>
<a href="/media/actors/">MediaActors</a>
<a href="/media/videos/">MediaVideos</a>
<a href="/media/lofi/">MediaLofi</a>
</div>
+7
View File
@@ -0,0 +1,7 @@
<div class="topnav">
<a href="/">Kontor</a>
<a href="/comic/comics">Comics</a>
<a href="/media/files">Media</a>
<a style="float:right" href="/login/">Login</a></li>
</div>
+28
View File
@@ -0,0 +1,28 @@
# ---------- Stage 1: Build ----------
FROM docker.io/library/golang:1.26-alpine AS builder
# Set the working directory
WORKDIR /app
# Ensure a portable, static-ish binary
ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64
# Copy and download dependencies
COPY go.mod go.sum ./
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 cmd/kontor/main.go
# ---------- Stage 2: Final ----------
FROM alpine:latest
# Set the working directory
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 /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"]
+11
View File
@@ -0,0 +1,11 @@
FROM docker.io/library/golang:1.26-alpine
# Install runtime dependencies you actually need
RUN apk add --no-cache ca-certificates tzdata curl git make musl-dev go
# Set the working directory
WORKDIR /app
# Copy the binary and set ownership
COPY ./kontor kontor
EXPOSE 8550
ENV DB_HOST=postgres DB_USER=kontor DB_PASSWORD=kontor DB_NAME=kontor DB_PORT=5432
# Set the entrypoint command
ENTRYPOINT ["/app/kontor"]
+8
View File
@@ -0,0 +1,8 @@
package assets
import (
"embed"
)
//go:embed style/* icons/*
var StaticFiles embed.FS
Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

+172
View File
@@ -0,0 +1,172 @@
* {
box-sizing: border-box;
}
body {
font-family: Arial;
padding: 10px;
background: lightgrey;
}
/* Header/Blog Title */
.header {
padding: 30px;
text-align: center;
background-color: lightblue;
}
.header h1 {
font-size: 50px;
}
/* Style the top navigation bar */
.topnav {
overflow: hidden;
background-color: darkgrey;
}
/* Style the topnav links */
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
/* Change color on hover */
.topnav a:hover {
background-color: #ddd;
color: black;
}
.subnav {
overflow: hidden;
background-color: grey;
}
.subnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center;
padding-top: 10px;
padding-left: 20px;
}
.form-inline label {
margin: 5px 10px 5px 0;
}
.form-inline input {
padding-right: 50px;
margin-right: 10px;
}
.form-inline button {
padding: 10px 20px;
background-color: dodgerblue;
border: 1px solid #ddd;
color: white;
border-radius: 10px;
}
.form-inline button:hover {
background-color: royalblue;
}
.pill-nav a {
display: inline-block;
color: white;
background-color: dodgerblue;
text-align: center;
padding: 10px;
text-decoration: none;
border-radius: 10px;
margin-left: 20px;
}
/* Change the color of links on mouse-over */
.pill-nav a:hover {
background-color: royalblue;
color: white;
}
/* Add a color to the active/current link */
.pill-nav a.active {
background-color: royalblue;
color: white;
}
.maincolumn {
float:left;
width: 100%;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
float: left;
width: 75%;
}
/* Right column */
.rightcolumn {
float: left;
width: 25%;
background-color: #f1f1f1;
padding-left: 20px;
}
/* Fake image */
.fakeimg {
background-color: #aaa;
width: 100%;
padding: 20px;
}
/* Add a card effect for articles */
.card {
background-color: white;
padding: 20px;
margin-top: 20px;
}
/* Clear floats after the columns */
.row::after {
content: "";
display: table;
clear: both;
}
/* Footer */
.footer {
padding: 20px;
text-align: center;
background: #ddd;
margin-top: 20px;
}
/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
.leftcolumn, .rightcolumn {
width: 100%;
padding: 0;
}
}
/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */
@media screen and (max-width: 400px) {
.topnav a {
float: none;
width: 100%;
}
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
# script/cibuild:
set -e
cd "$(dirname "$0")/.."
source version
echo " => Baue Image localhost/kontor-gin:$kontorVersion"
buildah build -t kontor-gin:$kontorVersion kontor-gin
+9
View File
@@ -0,0 +1,9 @@
package main
import (
"kontor-api-gin/internal/cmd"
)
func main() {
cmd.Execute()
}
+84
View File
@@ -0,0 +1,84 @@
package main
import (
"context"
"fmt"
"kontor-api-gin/internal/config"
"kontor-api-gin/internal/handlers"
"kontor-api-gin/internal/router"
"log"
"log/slog"
"net/http"
"os"
"os/signal"
"strconv"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/spf13/viper"
)
func main() {
slog.Info("Kontor started")
if err := config.InitConfig(); err != nil {
log.Fatalf("Failed to initialize config: %v", err)
}
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"),
)
db, err := config.NewDB(dsn)
if err != nil {
log.Fatal(err)
}
if err := db.AutoMigrate(); err != nil {
log.Fatal(err)
}
// Set Gin mode based on environment
// Production mode disables debug output
if viper.GetString("gin.mode") == "release" {
gin.SetMode(gin.ReleaseMode)
}
r := router.New(
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"))),
)
srv := &http.Server{
Addr: ":" + strconv.Itoa(viper.GetInt("port")),
Handler: r,
ReadHeaderTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 120 * time.Second,
}
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatal(err)
}
}()
slog.Info("server up", "address", srv.Addr)
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
_ = srv.Shutdown(ctx)
slog.Info("server stopped")
slog.Info("Kontor finished")
}
+71
View File
@@ -0,0 +1,71 @@
module kontor-api-gin
go 1.26.8
require (
github.com/gin-contrib/cors v1.7.2
github.com/gin-contrib/sessions v1.1.2
github.com/gin-contrib/slog v1.1.0
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
github.com/spf13/viper v1.21.0
golang.org/x/crypto v0.57.0
golang.org/x/time v0.16.0
gorm.io/driver/postgres v1.6.3
gorm.io/gorm v1.31.2
)
require (
github.com/bytedance/gopkg v0.1.4 // indirect
github.com/bytedance/sonic v1.15.4 // indirect
github.com/bytedance/sonic/loader v0.5.2 // indirect
github.com/cloudwego/base64x v0.1.7 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.15 // indirect
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.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
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.11.0 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.4.0 // indirect
github.com/leodido/go-urn v1.5.0 // indirect
github.com/mattn/go-isatty v0.0.24 // indirect
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
github.com/spf13/pflag v1.0.10 // indirect
github.com/stretchr/testify v1.12.1 // indirect
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
golang.org/x/sync v0.23.0 // indirect
golang.org/x/sys v0.48.0 // indirect
golang.org/x/text v0.42.0 // indirect
google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
resty.dev/v3 v3.0.0-rc.4 // indirect
)
+173
View File
@@ -0,0 +1,173 @@
github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM=
github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4=
github.com/bytedance/sonic v1.15.4 h1:FgtV/4aBHpla9AxuMpuuzVUpa/Cf3izufkxNmnEzdI8=
github.com/bytedance/sonic v1.15.4/go.mod h1:8e51yTPdY8M6t+vvGL1c2Y1xL9i+frEeIAQAEl75NUc=
github.com/bytedance/sonic/loader v0.5.2 h1:0QtP1gevc1OZ6/H8Lb9BRZiCXd1Ftjd3OKuj1T1lBIo=
github.com/bytedance/sonic/loader v0.5.2/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI=
github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI=
github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ=
github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw=
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=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.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=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.11.0 h1:IzBBtyK9AHqf98cctWFifYSci2hgQR/cd56wB4p+ogg=
github.com/jackc/pgx/v5 v5.11.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw=
github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.5.0 h1:pLqT2kq1zpHW/1D18QMjMpdtX7cekxqtJJjg5ANyWw0=
github.com/leodido/go-urn v1.5.0/go.mod h1:9BORnCDhdPBJNDEX+w1bJisa8yOKYi116VeO96s4ifE=
github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI=
github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.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=
github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4=
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.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=
golang.org/x/arch v0.31.0 h1:22MlEb14/O/EPCYHFxsDdv5TuLD5dMjT5e2QeJw4ULk=
golang.org/x/arch v0.31.0/go.mod h1:KcJSod3cqT2dKcjBxqTyGfbumNikqU9p5tHJinPJnuY=
golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA=
golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=
golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=
golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=
golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=
golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE=
golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s=
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.6.3 h1:bAn6O2pUa8LtpWEvL5NFU4+52Tfx8Ut7IVaIacCLcI0=
gorm.io/driver/postgres v1.6.3/go.mod h1:0c4fQA44XhOklXDkgtuKqysHCycTa5i9e3EIpDGCwXk=
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo=
gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
resty.dev/v3 v3.0.0-rc.4 h1:n3360yEcFiyrX5Vkc9XG3Y8kMM24alRBxJ9Ev1mLmqs=
resty.dev/v3 v3.0.0-rc.4/go.mod h1:NTOerrC/4T7/FE6tXIZGIysXXBdgNqwMZuKtxpea9NM=
+21
View File
@@ -0,0 +1,21 @@
package cmd
import (
"log/slog"
"github.com/spf13/cobra"
)
var addLinksCmd = &cobra.Command{
Use: "add-links",
Short: "Add Links",
Long: "Add Links",
// Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
slog.Info("add Links")
},
}
func init() {
rootCmd.AddCommand(addLinksCmd)
}
+70
View File
@@ -0,0 +1,70 @@
package cmd
import (
"kontor-api-gin/internal/models"
"log/slog"
"github.com/spf13/cobra"
"resty.dev/v3"
)
type Login struct {
Email string
Password string
}
type LoginResponse struct {
Token string
}
var checkCmd = &cobra.Command{
Use: "check",
Short: "Check Kontor Database",
Long: "Check Kontor Database to given file",
// Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
slog.Info("check 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"`
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", comics)
defer client.Close()
slog.Info("kontor.check_kontor.check_duplicate_links")
// check_duplicate_links(first_server, dirs)
slog.Info("kontor.check_kontor.check_media_dirs")
// check_media_dirs(first_server, dirs)
},
}
func init() {
rootCmd.AddCommand(checkCmd)
}
+126
View File
@@ -0,0 +1,126 @@
package cmd
import (
"encoding/json"
"kontor-api-gin/internal/models"
"log/slog"
"os"
"github.com/spf13/cobra"
"resty.dev/v3"
)
var exportCmd = &cobra.Command{
Use: "export",
Short: "Export Kontor Database",
Long: "Export Kontor Database to given file",
// Args: cobra.ExactArgs(1),
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")
},
}
func init() {
rootCmd.AddCommand(exportCmd)
}
+21
View File
@@ -0,0 +1,21 @@
package cmd
import (
"log/slog"
"github.com/spf13/cobra"
)
var importCmd = &cobra.Command{
Use: "import",
Short: "Import Kontor Database",
Long: "Import Kontor Database from given file",
// Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
slog.Info("import kontor")
},
}
func init() {
rootCmd.AddCommand(importCmd)
}
+42
View File
@@ -0,0 +1,42 @@
package cmd
import (
"fmt"
"log/slog"
"os"
"github.com/spf13/cobra"
)
var cfgFile string
var verbose int
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "kontor-cli",
Short: "A brief description of your application",
Long: `A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:
Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
// Uncomment the following line if your bare application
// has an action associated with it:
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
slog.Info("Verbosity level", "level", verbose)
},
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Oops. An error while executing Zero '%s'\n", err)
os.Exit(1)
}
}
func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.myapp.yaml)")
rootCmd.PersistentFlags().CountVarP(&verbose, "verbose", "v", "increase verbosity (-v, -vv, -vvv)")
}
+21
View File
@@ -0,0 +1,21 @@
package cmd
import (
"log/slog"
"github.com/spf13/cobra"
)
var syncCmd = &cobra.Command{
Use: "sync",
Short: "Sync Kontor Database",
Long: "Sync Kontor Database",
// Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
slog.Info("sync kontor")
},
}
func init() {
rootCmd.AddCommand(syncCmd)
}
+40
View File
@@ -0,0 +1,40 @@
package config
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
}
+35
View File
@@ -0,0 +1,35 @@
package config
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func NewDB(dsn string) (*gorm.DB, error) {
// Configure GORM with custom settings
// The logger helps with debugging SQL queries during development
return 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)
// slog.Info("Database connected successfully")
}
+7
View File
@@ -0,0 +1,7 @@
package globals
var Secret = []byte("secret")
const UserKey = "user"
const Version = "0.4.0"
+23
View File
@@ -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
}
+128
View File
@@ -0,0 +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) {
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, "/")
}
+64
View File
@@ -0,0 +1,64 @@
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
}
func (handler *ComicHandler) 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.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,
})
}
+34
View File
@@ -0,0 +1,34 @@
package handlers
import (
"kontor-api-gin/internal/globals"
"net/http"
"time"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/slog"
"github.com/gin-gonic/gin"
)
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)
logger.Info("IndexGetHandler", globals.UserKey, user)
c.HTML(http.StatusOK, "home", gin.H{
"title": "Kontor Gin",
"version": "0.4.0",
"message": "This is an index page...",
"user": user,
})
}
+23
View File
@@ -0,0 +1,23 @@
package handlers
import (
"kontor-api-gin/internal/repository"
"kontor-api-gin/internal/service"
"gorm.io/gorm"
)
type MediaHandler struct {
MediaActorHandler *MediaActorHandler
MediaFileHandler *MediaFileHandler
MediaLoFiHandler *MediaLoFiHandler
}
func NewMediaHandler(db *gorm.DB) *MediaHandler {
mediaHandler := &MediaHandler{
MediaActorHandler: &MediaActorHandler{Service: service.NewMediaActorService(repository.NewMediaActorRepository(db))},
MediaFileHandler: &MediaFileHandler{Service: service.NewMediaFileService(repository.NewMediaFileRepository(db))},
MediaLoFiHandler: &MediaLoFiHandler{Service: service.NewMediaLoFiService(repository.NewMediaLoFiRepository(db))},
}
return mediaHandler
}
@@ -0,0 +1,51 @@
package handlers
import (
"kontor-api-gin/internal/globals"
"kontor-api-gin/internal/models"
"kontor-api-gin/internal/repository"
"kontor-api-gin/internal/service"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type MediaActorHandler struct {
Service *service.MediaActorService
}
func NewMediaActorHandler(db *gorm.DB) *MediaActorHandler {
mediaActorHandler := &MediaActorHandler{
Service: service.NewMediaActorService(repository.NewMediaActorRepository(db)),
}
return mediaActorHandler
}
func (handler *MediaActorHandler) List(c *gin.Context) {
lofis, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
dtos := models.ConvertMediaActorsToDtos(lofis)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaActorHandler) ListPage(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
actors, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.HTML(http.StatusOK, "mediaactors", gin.H{
"title": "Kontor MediaActors",
"version": "0.4.0",
"message": "MediaActors...",
"actors": actors,
"user": user,
})
}
@@ -0,0 +1,54 @@
package handlers
import (
"kontor-api-gin/internal/globals"
"kontor-api-gin/internal/models"
"kontor-api-gin/internal/repository"
"kontor-api-gin/internal/service"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/slog"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type MediaFileHandler struct {
Service *service.MediaFileService
}
func NewMediaFileHandler(db *gorm.DB) *MediaFileHandler {
mediaFileHandler := &MediaFileHandler{
Service: service.NewMediaFileService(repository.NewMediaFileRepository(db)),
}
return mediaFileHandler
}
func (handler *MediaFileHandler) List(c *gin.Context) {
logger := slog.Get(c)
logger.Info("MediaFileHandler#List")
files, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
dtos := models.ConvertMediaFilesToDtos(files)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaFileHandler) ListPage(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
files, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.HTML(http.StatusOK, "mediafiles", gin.H{
"title": "Kontor MediaFiles",
"version": "0.4.0",
"message": "MediaFiles...",
"mediafiles": files,
"user": user,
})
}
@@ -0,0 +1,51 @@
package handlers
import (
"kontor-api-gin/internal/globals"
"kontor-api-gin/internal/models"
"kontor-api-gin/internal/repository"
"kontor-api-gin/internal/service"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type MediaLoFiHandler struct {
Service *service.MediaLoFiService
}
func NewMediaLoFiHandler(db *gorm.DB) *MediaLoFiHandler {
mediaLoFiHandler := &MediaLoFiHandler{
Service: service.NewMediaLoFiService(repository.NewMediaLoFiRepository(db)),
}
return mediaLoFiHandler
}
func (handler *MediaLoFiHandler) List(c *gin.Context) {
lofis, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
dtos := models.ConvertMediaLoFisToDtos(lofis)
c.JSON(http.StatusOK, dtos)
}
func (handler *MediaLoFiHandler) ListPage(c *gin.Context) {
session := sessions.Default(c)
user := session.Get(globals.UserKey)
lofis, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.HTML(http.StatusOK, "lofi", gin.H{
"title": "Kontor MediaFiles",
"version": "0.4.0",
"message": "MediaFiles...",
"lofis": lofis,
"user": user,
})
}
@@ -0,0 +1,21 @@
package handlers
import (
"kontor-api-gin/internal/service"
"net/http"
"github.com/gin-gonic/gin"
)
type PermissionHandler struct {
Service *service.PermissionService
}
func (handler *PermissionHandler) List(c *gin.Context) {
permissions, err := handler.Service.List(c.Request.Context())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, permissions)
}
+33
View File
@@ -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)
}
+33
View File
@@ -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)
}
+23
View File
@@ -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)
}
+33
View File
@@ -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)
}
+33
View File
@@ -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)
}
+29
View File
@@ -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
}
+21
View File
@@ -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
}
+13
View File
@@ -0,0 +1,13 @@
package helpers
import (
"strings"
)
func CheckUserPass(username, password string) bool {
return true
}
func EmptyUserPass(username, password string) bool {
return strings.Trim(username, " ") == "" || strings.Trim(password, " ") == ""
}
+90
View File
@@ -0,0 +1,90 @@
package helpers
import (
"fmt"
"strings"
"time"
"github.com/gin-contrib/slog"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
"github.com/spf13/viper"
)
func GenerateToken(profile_id string) (string, error) {
// token_lifespan := viper.GetInt("token_hour_lifespan")
claims := jwt.MapClaims{
"name": "Thomas Peetz",
"admin": true,
"authorized": true,
"sub": profile_id,
"exp": time.Now().Add(time.Hour * 72).Unix(),
}
// claims["authorized"] = true
// claims["profile_id"] = profile_id
// claims["exp"] = time.Now().Add(time.Hour * time.Duration(token_lifespan)).Unix()
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString([]byte(viper.GetString("api_secret")))
}
func TokenValid(c *gin.Context) error {
logger := slog.Get(c)
tokenString := ExtractToken(c)
_, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
logger.Info("TokenValid", "Unexpected signing method", token.Header["alg"])
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return []byte(viper.GetString("api_secret")), nil
})
if err != nil {
return err
}
return nil
}
func ExtractToken(c *gin.Context) string {
logger := slog.Get(c)
token := c.Query("token")
if token != "" {
logger.Info("ExtractToken", "token from query", token)
return token
}
bearerToken := c.Request.Header.Get("Authorization")
if len(strings.Split(bearerToken, " ")) == 2 {
logger.Info("ExtractToken", "token from query", token)
return strings.Split(bearerToken, " ")[1]
}
return ""
}
func ExtractTokenID(c *gin.Context) (string, error) {
tokenString := ExtractToken(c)
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return []byte(viper.GetString("api_secret")), nil
})
if err != nil {
return "", err
}
claims, ok := token.Claims.(jwt.MapClaims)
if ok && token.Valid {
uid, ok := claims["profile_id"].(string)
if !ok {
return "", err
}
return uid, nil
}
return "", nil
}
+26
View File
@@ -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()
}
}
+35
View File
@@ -0,0 +1,35 @@
package middleware
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
)
func JWT(secret []byte) gin.HandlerFunc {
return func(c *gin.Context) {
h := c.GetHeader("Authorization")
if !strings.HasPrefix(h, "Bearer ") {
c.AbortWithStatusJSON(http.StatusUnauthorized,
gin.H{"error": "missing bearer token"})
return
}
raw := strings.TrimPrefix(h, "Bearer ")
token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, jwt.ErrSignatureInvalid
}
return secret, nil
})
if err != nil || !token.Valid {
c.AbortWithStatusJSON(http.StatusUnauthorized,
gin.H{"error": "invalid token"})
return
}
claims := token.Claims.(jwt.MapClaims)
c.Set("profile_id", claims["sub"].(string))
c.Next()
}
}
@@ -0,0 +1,17 @@
package middleware
import (
"github.com/gin-gonic/gin"
"golang.org/x/time/rate"
)
func RateLimit(rps int, burst int) gin.HandlerFunc {
limiter := rate.NewLimiter(rate.Limit(rps), burst)
return func(c *gin.Context) {
if !limiter.Allow() {
c.AbortWithStatusJSON(429, gin.H{"error": "too many requests"})
return
}
c.Next()
}
}
@@ -0,0 +1,25 @@
package middleware
import (
"slices"
"github.com/gin-contrib/slog"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
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()
}
}
+22
View File
@@ -0,0 +1,22 @@
package models
import "time"
type Artist 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"`
WebLink string `gorm:"column:weblink" json:"weblink"`
}
func (artist *Artist) TableName() string {
return "artist"
}
type CreateArtistDTO struct {
Name string `json:"name" binding:"required"`
WebLink string `json:"weblink" binding:"required"`
}
+29
View File
@@ -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"`
}
+55
View File
@@ -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
}
+51
View File
@@ -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
}
+71
View File
@@ -0,0 +1,71 @@
package models
import (
"time"
)
type Comic 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"`
Title string `gorm:"uniqueIndex" json:"title"`
CurrentOrder bool `gorm:"column:current_order" json:"current_order"`
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"`
Volumes []Volume `gorm:"foreignKey:ComicID"`
ComicWorks []ComicWork `gorm:"foreignKey:ComicID"`
}
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"`
}
type UpdateComicDTO struct {
Title *string `json:"title,omitempty" binding:"omitempty"`
WebLink *string `json:"weblink,omitempty" binding:"omitempty"`
Completed *bool `json:"cimpleted,omitempty" binding:"omitempty"`
CurrentOrder *bool `json:"current_order,omitempty" binding:"omitempty"`
}
+21
View File
@@ -0,0 +1,21 @@
package models
import "time"
type ComicWork struct {
ID string `gorm:"type:string;primary_key;"`
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"`
ArtistID *string `gorm:"column:artist_id" json:"artist_id"`
Artist *Artist `gorm:"foreignKey:ArtistID"`
ComicID *string `gorm:"column:comic_id" json:"comic_id"`
Comic *Comic `gorm:"foreignKey:ComicID"`
WorkTypeID *string `gorm:"column:work_type_id" json:"work_type_id"`
WorkType *WorkType `gorm:"foreignKey:WorkTypeID"`
}
func (comic_work *ComicWork) TableName() string {
return "comic_work"
}
+26
View File
@@ -0,0 +1,26 @@
package models
import "time"
type Issue struct {
ID string `gorm:"type:string;primary_key;"`
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"`
InStock bool `gorm:"column:in_stock" json:"in_stock"`
IsRead bool `gorm:"column:is_read" json:"is_read"`
IssueNumber string `gorm:"column:issue_number" json:"issue_number"`
Title string `gorm:"column:title" json:"title"`
PublishedOn time.Time `gorm:"column:published_on" json:"published_on"`
ComicID *string `gorm:"column:comic_id" json:"comic_id"`
Comic *Comic `gorm:"foreignKey:ComicID"`
StoryArcID *string `gorm:"column:story_arc_id" json:"story_arc_id"`
StoryArc *StoryArc `gorm:"foreignKey:StoryArcID"`
VolumeID *string `gorm:"column:volume_id" json:"volume_id"`
Volume *Volume `gorm:"foreignKey:VolumeID"`
}
func (issue *Issue) TableName() string {
return "issue"
}
+21
View File
@@ -0,0 +1,21 @@
package models
import "time"
type IssueWork struct {
ID string `gorm:"type:string;primary_key;"`
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"`
ArtistID *string `gorm:"column:artist_id" json:"artist_id"`
Artist *Artist `gorm:"foreignKey:ArtistID"`
IssueID *string `gorm:"column:issue_id" json:"issue_id"`
Issue *Issue `gorm:"foreignKey:IssueID"`
WorkTypeID *string `gorm:"column:work_type_id" json:"work_type_id"`
WorkType *WorkType `gorm:"foreignKey:WorkTypeID"`
}
func (issue_work *IssueWork) TableName() string {
return "issue_work"
}
+45
View File
@@ -0,0 +1,45 @@
package models
import "time"
type MediaActor struct {
ID string `gorm:"type:string;primary_key;" json:"id"`
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
Version int `gorm:"default:0" json:"version"`
Name string `gorm:"column:name" json:"name"`
WebLink string `gorm:"column:url" json:"url"`
MediaActorFiles []MediaActorFile `gorm:"foreignKey:MediaActorID" json:"media_actor_files"`
}
func (media_actor *MediaActor) TableName() string {
return "media_actor"
}
type MediaActorDTO struct {
ID string `json:"id" binding:"required"`
CreatedAt time.Time `json:"created_date"`
UpdatedAt time.Time `json:"last_modified_date"`
DeletedAt *time.Time `json:"deleted_date"`
Version int `json:"version"`
Name string `json:"name"`
WebLink string `json:"url"`
}
func ConvertMediaActorsToDtos(actors []MediaActor) []MediaActorDTO {
dtos := make([]MediaActorDTO, len(actors))
for i, actor := range actors {
dtos[i] = MediaActorDTO{
ID: actor.ID,
CreatedAt: actor.CreatedAt,
UpdatedAt: actor.UpdatedAt,
DeletedAt: actor.DeletedAt,
Version: actor.Version,
Name: actor.Name,
WebLink: actor.WebLink,
}
}
return dtos
}
@@ -0,0 +1,45 @@
package models
import "time"
type MediaActorFile struct {
ID string `gorm:"type:string;primary_key;" json:"id"`
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
Version int `gorm:"default:0" json:"version"`
MediaActorID *string `gorm:"column:media_actor_id" json:"media_actor_id"`
MediaActor *MediaActor `gorm:"foreignKey:MediaActorID" json:"media_actor"`
MediaFileID *string `form:"column:media_file_id" json:"media_file_id"`
MediaFile *MediaFile `gorm:"foreignKey:MediaFileID" json:"media_file"`
}
func (media_file *MediaActorFile) TableName() string {
return "media_actor_file"
}
type MediaActorFileDTO struct {
ID string `json:"id" binding:"required"`
CreatedAt time.Time `json:"created_date"`
UpdatedAt time.Time `json:"last_modified_date"`
DeletedAt *time.Time `json:"deleted_date"`
Version int `json:"version"`
MediaActorID *string `json:"media_actor_id"`
MediaFileID *string `json:"media_file_id"`
}
func ConvertMediaActorFilesToDtos(actor_files []MediaActorFile) []MediaActorFileDTO {
dtos := make([]MediaActorFileDTO, len(actor_files))
for i, actor_file := range actor_files {
dtos[i] = MediaActorFileDTO{
ID: actor_file.ID,
CreatedAt: actor_file.CreatedAt,
UpdatedAt: actor_file.UpdatedAt,
DeletedAt: actor_file.DeletedAt,
Version: actor_file.Version,
MediaActorID: actor_file.MediaActorID,
MediaFileID: actor_file.MediaFileID,
}
}
return dtos
}
@@ -0,0 +1,46 @@
package models
import "time"
type MediaArticle struct {
ID string `gorm:"type:string;primary_key;" json:"id"`
CreatedAt time.Time `gorm:"column:created_date" json:"created_date"`
UpdatedAt time.Time `gorm:"column:last_modified_date" json:"last_modified_date"`
DeletedAt *time.Time `gorm:"column:deleted_date" json:"deleted_date"`
Version int `gorm:"default:0" json:"version"`
Review bool `gorm:"column:review" json:"review"`
Title string `gorm:"size:300, column:title" json:"title"`
WebLink string `gorm:"column:url" json:"url"`
}
func (media_article *MediaArticle) TableName() string {
return "media_article"
}
type MediaArticleDTO struct {
ID string `json:"id" binding:"required"`
CreatedAt time.Time `json:"created_date"`
UpdatedAt time.Time `json:"last_modified_date"`
DeletedAt *time.Time `json:"deleted_date"`
Version int `json:"version"`
Review bool `json:"review"`
Title string `json:"title"`
WebLink string `json:"url"`
}
func ConvertMediaArticlesToDtos(media_articles []MediaArticle) []MediaArticleDTO {
dtos := make([]MediaArticleDTO, len(media_articles))
for i, media_article := range media_articles {
dtos[i] = MediaArticleDTO{
ID: media_article.ID,
CreatedAt: media_article.CreatedAt,
UpdatedAt: media_article.UpdatedAt,
DeletedAt: media_article.DeletedAt,
Version: media_article.Version,
Review: media_article.Review,
Title: media_article.Title,
WebLink: media_article.WebLink,
}
}
return dtos
}
+60
View File
@@ -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
}
+52
View File
@@ -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
}
+58
View File
@@ -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
}
+26
View File
@@ -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"`
}
+44
View File
@@ -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
}
+48
View File
@@ -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
}
+55
View File
@@ -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"`
}
+54
View File
@@ -0,0 +1,54 @@
package models
import "time"
type Publisher struct {
ID string `gorm:"type:string;primary_key;"`
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"`
WebLink string `gorm:"column:weblink" json:"weblink"`
ParentPublisherID *string `gorm:"column:parent_publisher_id" json:"parent_publisher_id"`
ParentPublisher *Publisher `gorm:"foreignKey:ParentPublisherID"`
Imprints []Publisher `gorm:"foreignKey:ParentPublisherID"`
Comics []Comic `gorm:"foreignKey:PublisherID"`
}
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"`
}
+53
View File
@@ -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
}
+45
View File
@@ -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"`
}
+20
View File
@@ -0,0 +1,20 @@
package models
import "time"
type StoryArc struct {
ID string `gorm:"type:string;primary_key;"`
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"`
ComicID *string `gorm:"column:comic_id" json:"comic_id"`
Comic *Comic `gorm:"foreignKey:ComicID"`
VolumeID *string `gorm:"column:volume_id" json:"volume_id"`
Volume *Volume `gorm:"foreignKey:VolumeID"`
}
func (story_arc *StoryArc) TableName() string {
return "story_arc"
}
+48
View File
@@ -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
}
+31
View File
@@ -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"`
}
@@ -0,0 +1,20 @@
package models
import "time"
type TradePaperback struct {
ID string `gorm:"type:string;primary_key;"`
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"`
IssueStart int `gorm:"column:issue_start" json:"issue_start"`
IssueEnd int `gorm:"column:issue_end" json:"issue_end"`
ComicID *string `gorm:"column:comic_id" json:"comic_id"`
Comic *Comic `gorm:"foreignKey:ComicID"`
}
func (trade_paperback *TradePaperback) TableName() string {
return "trade_paperback"
}
+42
View File
@@ -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
}
+18
View File
@@ -0,0 +1,18 @@
package models
import "time"
type Volume struct {
ID string `gorm:"type:string;primary_key;"`
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"`
ComicID *string `gorm:"column:comic_id" json:"comic_id"`
Comic *Comic `gorm:"foreignKey:ComicID"`
}
func (volume *Volume) TableName() string {
return "volume"
}

Some files were not shown because too many files have changed in this diff Show More