Compare commits
No commits in common. "master" and "EditProjects" have entirely different histories.
master
...
EditProjec
20
.env.example
20
.env.example
@ -1,20 +0,0 @@
|
||||
JWT_SECRET=temp123
|
||||
ENVIRONMENT=docker
|
||||
WEB_PORT=4000
|
||||
API_PORT=4001
|
||||
|
||||
# -
|
||||
# Database
|
||||
# -
|
||||
# IP address of database
|
||||
POSTGRES_HOST=
|
||||
# Database port
|
||||
POSTGRES_PORT=
|
||||
# Database username
|
||||
POSTGRES_USER=
|
||||
# The name of the database to connect to
|
||||
POSTGRES_DB=portfolio
|
||||
# Database password
|
||||
POSTGRES_PASSWORD=
|
||||
# Whether or not to use SSL ("verify-full" or "disable")
|
||||
SSL_MODE=disable
|
||||
66
.github/workflows/Deploy-docker.yml
vendored
66
.github/workflows/Deploy-docker.yml
vendored
@ -17,57 +17,39 @@ jobs:
|
||||
- name: 'Create env file'
|
||||
run: |
|
||||
touch .env
|
||||
echo WEB_PORT=4000 >> .env
|
||||
echo API_PORT=4001 >> .env
|
||||
echo JWT_SECRET=${{secrets.JWT_SECRET}} >> .env
|
||||
echo POSTGRES_HOST=192.168.1.200 >> .env
|
||||
echo POSTGRES_PORT=5099 >> .env
|
||||
echo POSTGRES_USER=postgres >> .env
|
||||
echo POSTGRES_DB=portfolio >> .env
|
||||
echo POSTGRES_PASSWORD=${{secrets.POSTGRES_PASSWORD}} >> .env
|
||||
echo SSL_MODE=disable >> .env
|
||||
echo ENVIRONMENT=docker >> .env
|
||||
echo POSTGRES_HOST=${{ secrets.POSTGRES_HOST }} >> .env
|
||||
echo POSTGRES_PORT=${{ secrets.POSTGRES_PORT }} >> .env
|
||||
echo POSTGRES_USER=${{ secrets.POSTGRES_USER }} >> .env
|
||||
echo POSTGRES_DB=${{ secrets.POSTGRES_DB }} >> .env
|
||||
echo POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} >> .env
|
||||
echo SSL_MODE=${{ secrets.SSL_MODE }} >> .env
|
||||
- name: Build the Docker image
|
||||
run: docker compose build
|
||||
- name: Docker login
|
||||
run: docker login gitea.kleinsense.nl -p ${{secrets.docker_password}} -u ${{secrets.docker_username}}
|
||||
- name: Docker push
|
||||
run: docker push gitea.kleinsense.nl/dariusklein/portfolio:latest
|
||||
- name: Docker push
|
||||
run: docker push gitea.kleinsense.nl/dariusklein/portfolio-docs:latest
|
||||
run: |
|
||||
docker push docker.dariusklein.nl/portfolio:latest
|
||||
docker push docker.dariusklein.nl/portfolio-docs:latest
|
||||
|
||||
publish-docs:
|
||||
publish:
|
||||
|
||||
needs: build
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: self-hosted
|
||||
|
||||
steps:
|
||||
- name: Docker stop
|
||||
run: docker stop darius-portfolio-docs || true
|
||||
- name: Docker remove
|
||||
run: docker rm darius-portfolio-docs || true
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
sparse-checkout: |
|
||||
docker-compose.yml
|
||||
- name: copy file
|
||||
run: mv docker-compose.yml /home/darius/portfolio
|
||||
- name: Docker login
|
||||
run: docker login gitea.kleinsense.nl -p ${{secrets.docker_password}} -u ${{secrets.docker_username}}
|
||||
run: docker login docker.dariusklein.nl -u Darius -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Docker pull
|
||||
run: docker pull gitea.kleinsense.nl/dariusklein/portfolio-docs:latest
|
||||
run: |
|
||||
cd /home/darius/portfolio
|
||||
docker compose pull
|
||||
- name: Docker run
|
||||
run: docker run --restart=always -dit -p 4002:80 --name darius-portfolio-docs gitea.kleinsense.nl/dariusklein/portfolio-docs:latest
|
||||
|
||||
publish-portfolio:
|
||||
|
||||
needs: build
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Docker stop
|
||||
run: docker stop darius-portfolio-server || true
|
||||
- name: Docker remove
|
||||
run: docker rm darius-portfolio-server || true
|
||||
- name: Docker login
|
||||
run: docker login gitea.kleinsense.nl -p ${{secrets.docker_password}} -u ${{secrets.docker_username}}
|
||||
- name: Docker pull
|
||||
run: docker pull gitea.kleinsense.nl/dariusklein/portfolio:latest
|
||||
- name: Docker run
|
||||
run: docker run --restart=always -dit -p 4000:4000 -p 4001:4001 --name darius-portfolio-server gitea.kleinsense.nl/dariusklein/portfolio:latest
|
||||
run: |
|
||||
cd /home/darius/portfolio
|
||||
docker compose up -d
|
||||
|
||||
@ -19,8 +19,7 @@ FROM gcr.io/distroless/base-debian12
|
||||
|
||||
COPY --from=build /go/portfolio .
|
||||
|
||||
COPY .env .
|
||||
|
||||
ADD .env .
|
||||
ADD ./web/assets ./web/assets
|
||||
|
||||
# Expose port 8080 for incoming traffic
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"portfolio/api/handlers"
|
||||
)
|
||||
|
||||
func Routes() *http.ServeMux {
|
||||
log.Println("Setup web routes")
|
||||
func ApiRoutes() *http.ServeMux {
|
||||
// Create a new request multiplexer
|
||||
// Take incoming requests and dispatch them to the matching webHandler
|
||||
mux := http.NewServeMux()
|
||||
@ -30,7 +28,6 @@ func Routes() *http.ServeMux {
|
||||
mux.HandleFunc("PATCH /projects", handlers.UpdateProjectsHandler)
|
||||
mux.HandleFunc("GET /project/{id}", handlers.GetProjectHandler)
|
||||
mux.HandleFunc("GET /projects", handlers.GetProjectsHandler)
|
||||
mux.HandleFunc("GET /projects/backup", handlers.GetProjectsBackupHandler)
|
||||
|
||||
return mux
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
module openAPI
|
||||
|
||||
go 1.24.0
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/a-h/respond v0.0.2
|
||||
@ -8,19 +8,17 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/getkin/kin-openapi v0.132.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.1 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/getkin/kin-openapi v0.124.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/invopop/yaml v0.3.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/tools v0.33.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/tools v0.20.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@ -6,16 +6,10 @@ 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/getkin/kin-openapi v0.124.0 h1:VSFNMB9C9rTKBnQ/fpyDU8ytMTr4dWI9QovSKj9kz/M=
|
||||
github.com/getkin/kin-openapi v0.124.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM=
|
||||
github.com/getkin/kin-openapi v0.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk=
|
||||
github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
|
||||
github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
|
||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
|
||||
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
|
||||
github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
@ -30,14 +24,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
|
||||
github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=
|
||||
github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -50,20 +38,12 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc=
|
||||
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
|
||||
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
|
||||
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
|
||||
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
|
||||
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=
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"github.com/a-h/respond"
|
||||
"github.com/a-h/rest"
|
||||
"net/http"
|
||||
"portfolio/api/types"
|
||||
"portfolio/database/ent"
|
||||
)
|
||||
|
||||
func RegisterProjectEndpoints() {
|
||||
@ -21,7 +21,7 @@ func RegisterProjectEndpoints() {
|
||||
Regexp: `\d+`,
|
||||
}).
|
||||
HasDescription("Update project by id").
|
||||
HasRequestModel(rest.ModelOf[types.Project]()).
|
||||
HasRequestModel(rest.ModelOf[ent.Project]()).
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[string]()).
|
||||
HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()).
|
||||
HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()).
|
||||
@ -30,7 +30,7 @@ func RegisterProjectEndpoints() {
|
||||
|
||||
api.Patch("/projects").
|
||||
HasDescription("Update projects WIP").
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[[]types.Project]()).
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[[]ent.Project]()).
|
||||
HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()).
|
||||
HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]()).
|
||||
HasResponseModel(http.StatusUnauthorized, rest.ModelOf[string]())
|
||||
@ -41,12 +41,12 @@ func RegisterProjectEndpoints() {
|
||||
Regexp: `\d+`,
|
||||
}).
|
||||
HasDescription("Get project by id").
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[types.Project]()).
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[ent.Project]()).
|
||||
HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()).
|
||||
HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]())
|
||||
|
||||
api.Get("/projects").
|
||||
HasDescription("Get projects").
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[[]types.Project]()).
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[[]ent.Project]()).
|
||||
HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]())
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import (
|
||||
"github.com/a-h/rest"
|
||||
"net/http"
|
||||
"portfolio/api/types"
|
||||
"portfolio/database/ent"
|
||||
)
|
||||
|
||||
func RegisterUserEndpoints() {
|
||||
@ -14,14 +15,14 @@ func RegisterUserEndpoints() {
|
||||
Regexp: `\d+`,
|
||||
}).
|
||||
HasDescription("Get user by uid.").
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[types.User]()).
|
||||
HasResponseModel(http.StatusOK, rest.ModelOf[ent.User]()).
|
||||
HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()).
|
||||
HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()).
|
||||
HasResponseModel(http.StatusUnprocessableEntity, rest.ModelOf[respond.Error]())
|
||||
|
||||
api.Post("/register").
|
||||
HasDescription("Register.").
|
||||
HasRequestModel(rest.ModelOf[types.User]()).
|
||||
HasRequestModel(rest.ModelOf[ent.User]()).
|
||||
HasResponseModel(http.StatusCreated, rest.ModelOf[string]()).
|
||||
HasResponseModel(http.StatusBadRequest, rest.ModelOf[string]()).
|
||||
HasResponseModel(http.StatusInternalServerError, rest.ModelOf[respond.Error]()).
|
||||
|
||||
@ -6,22 +6,26 @@ import (
|
||||
"net/http"
|
||||
"portfolio/api/service/bcrypt"
|
||||
"portfolio/api/service/jwt"
|
||||
"portfolio/api/types"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/query"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Login(w http.ResponseWriter, r *http.Request) {
|
||||
var u *types.LoginUser
|
||||
var u *ent.User
|
||||
|
||||
if r.Header.Get("HX-Request") == "true" {
|
||||
u = handleHtmxLogin(r)
|
||||
} else {
|
||||
u = handleHttpLogin(w, r, u)
|
||||
isHtmx := r.Header.Get("HX-Request")
|
||||
|
||||
if isHtmx == "true" {
|
||||
u = &ent.User{
|
||||
Email: r.PostFormValue("email"),
|
||||
Password: r.PostFormValue("password"),
|
||||
}
|
||||
} else {
|
||||
err := json.NewDecoder(r.Body).Decode(&u)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
return
|
||||
}
|
||||
|
||||
User, err := query.GetLogin(context.Background(), u)
|
||||
@ -30,18 +34,16 @@ func Login(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !bcrypt.CheckPasswordHash(u.Password, User.Password) {
|
||||
UnauthorizedHandler(w)
|
||||
return
|
||||
}
|
||||
if bcrypt.CheckPasswordHash(u.Password, User.Password) {
|
||||
|
||||
jwtToken := jwt.CreateUserJWT(User.Name, User.ID, string(User.Role))
|
||||
|
||||
cookie := &http.Cookie{
|
||||
Name: "jwt",
|
||||
if jwtToken != "" {
|
||||
|
||||
cookie := &http.Cookie{Name: "jwt",
|
||||
Value: jwtToken,
|
||||
HttpOnly: true,
|
||||
Secure: true,
|
||||
//HttpOnly: true,
|
||||
//Secure: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Expires: time.Now().Add(24 * time.Hour),
|
||||
}
|
||||
@ -50,21 +52,16 @@ func Login(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err = w.Write([]byte("login success"))
|
||||
}
|
||||
|
||||
func handleHtmxLogin(r *http.Request) *types.LoginUser {
|
||||
return &types.LoginUser{
|
||||
Email: r.PostFormValue("email"),
|
||||
Password: r.PostFormValue("password"),
|
||||
}
|
||||
}
|
||||
|
||||
func handleHttpLogin(w http.ResponseWriter, r *http.Request, u *types.LoginUser) *types.LoginUser {
|
||||
if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
|
||||
return
|
||||
} else {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
UnauthorizedHandler(w)
|
||||
return
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
func CanEdit(w http.ResponseWriter, r *http.Request) {
|
||||
@ -73,12 +70,14 @@ func CanEdit(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(""))
|
||||
return
|
||||
}
|
||||
if audience == "owner" || audience == "admin" {
|
||||
if audience == "owner" || audience == "visitor" {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("<button class=\"button is-link\">Edit</button>"))
|
||||
} else {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(""))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,39 +1,55 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
import "net/http"
|
||||
|
||||
func InternalServerErrorHandler(w http.ResponseWriter, err error) {
|
||||
setError(w, http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
func NotFoundHandler(w http.ResponseWriter) {
|
||||
setError(w, http.StatusNotFound, "404 Not Found")
|
||||
}
|
||||
|
||||
func BadRequestHandler(w http.ResponseWriter) {
|
||||
setError(w, http.StatusBadRequest, "404 Not Found")
|
||||
}
|
||||
|
||||
func UnprocessableEntityHandler(w http.ResponseWriter, err error) {
|
||||
setError(w, http.StatusUnprocessableEntity, err.Error())
|
||||
}
|
||||
|
||||
func UnauthorizedHandler(w http.ResponseWriter) {
|
||||
log.Println("unauthorized")
|
||||
setError(w, http.StatusUnauthorized, "Unauthorized")
|
||||
}
|
||||
|
||||
func NotImplementedHandler(w http.ResponseWriter) {
|
||||
setError(w, http.StatusNotImplemented, "WORK IN PROGRESS")
|
||||
}
|
||||
|
||||
func setError(w http.ResponseWriter, httpStatus int, errorMessage string) {
|
||||
w.WriteHeader(httpStatus)
|
||||
if _, err := w.Write([]byte(errorMessage)); err != nil {
|
||||
log.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError) //set http status
|
||||
_, err = w.Write([]byte(err.Error())) //set response message
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NotFoundHandler(w http.ResponseWriter) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
_, err := w.Write([]byte("404 Not Found"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func BadRequestHandler(w http.ResponseWriter) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, err := w.Write([]byte("400 Bad Request"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func UnprocessableEntityHandler(w http.ResponseWriter, err error) {
|
||||
w.WriteHeader(http.StatusUnprocessableEntity) //set http status
|
||||
_, err = w.Write([]byte(err.Error())) //set response message
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func UnauthorizedHandler(w http.ResponseWriter) {
|
||||
w.WriteHeader(http.StatusUnauthorized) //set http status
|
||||
_, err := w.Write([]byte("Unauthorized")) //set response message
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NotImplementedHandler(w http.ResponseWriter) {
|
||||
w.WriteHeader(http.StatusNotImplemented) //set http status
|
||||
_, err := w.Write([]byte("WORK IN PROGRESS"))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -4,13 +4,11 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"portfolio/api/service/jwt"
|
||||
"portfolio/api/service/parse"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/query"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CreateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -23,12 +21,14 @@ func CreateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var p *ent.Project
|
||||
|
||||
if err = json.NewDecoder(r.Body).Decode(&p); err != nil {
|
||||
err = json.NewDecoder(r.Body).Decode(&p)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = query.CreateProject(context.Background(), *p, id); err != nil {
|
||||
err = query.CreateProject(context.Background(), *p, id)
|
||||
if err != nil {
|
||||
UnprocessableEntityHandler(w, err)
|
||||
return
|
||||
}
|
||||
@ -36,7 +36,8 @@ func CreateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if _, _, err := jwt.VerifyUser(r); err != nil {
|
||||
_, _, err := jwt.VerifyUser(r)
|
||||
if err != nil {
|
||||
UnauthorizedHandler(w)
|
||||
return
|
||||
}
|
||||
@ -46,7 +47,6 @@ func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
projectID, err := strconv.Atoi(r.PathValue("id"))
|
||||
if err != nil {
|
||||
BadRequestHandler(w)
|
||||
return
|
||||
}
|
||||
|
||||
p, err = query.GetFullProject(context.Background(), projectID)
|
||||
@ -55,12 +55,14 @@ func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewDecoder(r.Body).Decode(&p); err != nil {
|
||||
err = json.NewDecoder(r.Body).Decode(&p)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = query.UpdateProject(context.Background(), *p, projectID); err != nil {
|
||||
err = query.UpdateProject(context.Background(), *p, projectID)
|
||||
if err != nil {
|
||||
UnprocessableEntityHandler(w, err)
|
||||
return
|
||||
}
|
||||
@ -68,19 +70,19 @@ func UpdateProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func UpdateProjectsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var newProjects []*ent.Project
|
||||
var p []*ent.Project
|
||||
var err error
|
||||
|
||||
isHtmx := r.Header.Get("HX-Request")
|
||||
|
||||
if _, _, err := jwt.VerifyUser(r); err != nil {
|
||||
_, _, err := jwt.VerifyUser(r)
|
||||
if err != nil {
|
||||
UnauthorizedHandler(w)
|
||||
return
|
||||
}
|
||||
|
||||
var newProjects []*ent.Project
|
||||
var p []*ent.Project
|
||||
|
||||
if isHtmx == "true" {
|
||||
p = parse.ProjectInput(r)
|
||||
p = parse.ParseProjectInput(r)
|
||||
} else {
|
||||
|
||||
p, err = query.GetFullProjects(context.Background())
|
||||
@ -105,7 +107,8 @@ func UpdateProjectsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
for _, project := range p {
|
||||
if err = query.UpdateProject(context.Background(), *project, project.ID); err != nil {
|
||||
err = query.UpdateProject(context.Background(), *project, project.ID)
|
||||
if err != nil {
|
||||
UnprocessableEntityHandler(w, err)
|
||||
return
|
||||
}
|
||||
@ -128,8 +131,8 @@ func GetProjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if err = json.NewEncoder(w).Encode(p); err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
err = json.NewEncoder(w).Encode(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -144,34 +147,8 @@ func GetProjectsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if err = json.NewEncoder(w).Encode(p); err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func GetProjectsBackupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
p, err := query.GetProjects(context.Background())
|
||||
err = json.NewEncoder(w).Encode(p)
|
||||
if err != nil {
|
||||
UnprocessableEntityHandler(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
backup, _ := json.Marshal(p)
|
||||
|
||||
if err = os.WriteFile(
|
||||
"/web/assets/json/backup-"+strconv.Itoa(int(time.Now().Unix()))+".json",
|
||||
backup,
|
||||
0644,
|
||||
); err != nil {
|
||||
UnprocessableEntityHandler(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(p); err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,28 +6,30 @@ import (
|
||||
"net/http"
|
||||
"portfolio/api/service/bcrypt"
|
||||
"portfolio/api/service/validate"
|
||||
"portfolio/api/types"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/ent/user"
|
||||
"portfolio/database/query"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var u *types.RegisterUser
|
||||
var u *ent.User
|
||||
|
||||
if r.Header.Get("HX-Request") == "true" {
|
||||
u = &types.RegisterUser{
|
||||
isHtmx := r.Header.Get("HX-Request")
|
||||
|
||||
if isHtmx == "true" {
|
||||
u = &ent.User{
|
||||
Name: r.PostFormValue("name"),
|
||||
Password: r.PostFormValue("password"),
|
||||
Email: r.PostFormValue("email"),
|
||||
//Role: user.Role(r.PostFormValue("role")),
|
||||
Role: user.Role(r.PostFormValue("role")),
|
||||
}
|
||||
} else {
|
||||
if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
|
||||
err := json.NewDecoder(r.Body).Decode(&u)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !validate.UserIsValid(u) {
|
||||
BadRequestHandler(w)
|
||||
return
|
||||
@ -36,13 +38,14 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
//hash password
|
||||
u.Password, _ = bcrypt.HashPassword(u.Password)
|
||||
|
||||
if err := query.CreateUser(context.Background(), *u); err != nil {
|
||||
err := query.CreateUser(context.Background(), *u)
|
||||
if err != nil {
|
||||
UnprocessableEntityHandler(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
w.Write([]byte("user created"))
|
||||
_, err = w.Write([]byte("user created"))
|
||||
|
||||
}
|
||||
|
||||
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
@ -60,7 +63,8 @@ func GetUserHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if err = json.NewEncoder(w).Encode(User); err != nil {
|
||||
err = json.NewEncoder(w).Encode(User)
|
||||
if err != nil {
|
||||
InternalServerErrorHandler(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ProjectInput(r *http.Request) []*ent.Project {
|
||||
func ParseProjectInput(r *http.Request) []*ent.Project {
|
||||
b, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package validate
|
||||
|
||||
import (
|
||||
"portfolio/api/types"
|
||||
"portfolio/database/ent"
|
||||
)
|
||||
|
||||
func UserIsValid(u *types.RegisterUser) bool {
|
||||
func UserIsValid(u *ent.User) bool {
|
||||
if len(u.Name) > 0 &&
|
||||
len(u.Email) > 0 &&
|
||||
len(u.Password) > 0 {
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
package types
|
||||
|
||||
type Project struct {
|
||||
ID int `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
ImageURL string `json:"image_url,omitempty"`
|
||||
DocURL string `json:"doc_url,omitempty"`
|
||||
}
|
||||
@ -1,28 +1,10 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"portfolio/database/ent/user"
|
||||
)
|
||||
|
||||
type Username struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type LoginUser struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
}
|
||||
|
||||
type RegisterUser struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID int `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Password string `json:"-"`
|
||||
Role user.Role `json:"role,omitempty"`
|
||||
Email string
|
||||
Password string
|
||||
}
|
||||
|
||||
@ -2,12 +2,6 @@ FROM golang:latest as openApiGen
|
||||
|
||||
ADD . .
|
||||
|
||||
# Download and install any required dependencies
|
||||
RUN go mod download
|
||||
|
||||
# Build the Go app
|
||||
RUN go build .
|
||||
|
||||
RUN go run ./api/docs/openAPI
|
||||
|
||||
FROM registry.jetbrains.team/p/writerside/builder/writerside-builder:241.15989 as build
|
||||
|
||||
@ -1,539 +1,19 @@
|
||||
{
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Error": {
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"statusCode": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"message",
|
||||
"statusCode"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"portfolio_api_types_LoginUser": {
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"portfolio_api_types_Project": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"doc_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"image_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"portfolio_api_types_User": {
|
||||
"properties": {
|
||||
"-": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"-"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {},
|
||||
"info": {
|
||||
"title": "portfolio",
|
||||
"version": "0.0.0"
|
||||
},
|
||||
"openapi": "3.0.0",
|
||||
"paths": {
|
||||
"/check": {
|
||||
"/nfc/{uid}": {
|
||||
"get": {
|
||||
"description": "check for user jwt cookie",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/htmx/canEdit": {
|
||||
"get": {
|
||||
"description": "check if user is allowed to edit",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/login": {
|
||||
"post": {
|
||||
"description": "Login.",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_LoginUser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"401": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/project": {
|
||||
"post": {
|
||||
"description": "Create project",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"401": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/project/{id}": {
|
||||
"get": {
|
||||
"description": "Get project by id",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "id of the project",
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"pattern": "\\d+",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_Project"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"description": "Update project by id",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "id of the project",
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"pattern": "\\d+",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"401": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/projects": {
|
||||
"get": {
|
||||
"description": "Get projects",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_Project"
|
||||
},
|
||||
"nullable": true,
|
||||
"type": "array"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"description": "Update projects WIP",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_Project"
|
||||
},
|
||||
"nullable": true,
|
||||
"type": "array"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"401": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/register": {
|
||||
"post": {
|
||||
"description": "Register.",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_User"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/{uid}": {
|
||||
"get": {
|
||||
"description": "Get user by uid.",
|
||||
"description": "Get nfc data by uid.",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "id of the user",
|
||||
"in": "path",
|
||||
"name": "id",
|
||||
"name": "uid",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"pattern": "\\d+",
|
||||
@ -543,16 +23,6 @@
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/portfolio_api_types_User"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
@ -562,26 +32,6 @@
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"422": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/Error"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": ""
|
||||
},
|
||||
"default": {
|
||||
"description": ""
|
||||
}
|
||||
@ -590,11 +40,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
: {
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,16 +7,8 @@
|
||||
start-page="test.md">
|
||||
|
||||
<toc-element topic="test.md"/>
|
||||
<toc-element topic="API_Reference.topic">
|
||||
<toc-element topic="user_uid_GET.topic"/>
|
||||
<toc-element topic="register_POST.topic"/>
|
||||
<toc-element topic="projects_PATCH.topic"/>
|
||||
<toc-element topic="projects_GET.topic"/>
|
||||
<toc-element topic="project_id_PATCH.topic"/>
|
||||
<toc-element topic="project_id_GET.topic"/>
|
||||
<toc-element topic="project_POST.topic"/>
|
||||
<toc-element topic="login_POST.topic"/>
|
||||
<toc-element topic="htmx_canEdit_GET.topic"/>
|
||||
<toc-element topic="check_GET.topic"/>
|
||||
<toc-element topic="API_Reference.md">
|
||||
<toc-element topic="Schemas.md"/>
|
||||
<toc-element topic="nfc_uid_GET.md"/>
|
||||
</toc-element>
|
||||
</instance-profile>
|
||||
@ -18,16 +18,4 @@
|
||||
<description>Created after removal of "About portfolio" from portfolio</description>
|
||||
<accepts>starter-topic.html</accepts>
|
||||
</rule>
|
||||
<rule id="197e2e0d">
|
||||
<description>Created after removal of "Schemas" from portfolio</description>
|
||||
<accepts>Schemas.html</accepts>
|
||||
</rule>
|
||||
<rule id="32e9b651">
|
||||
<description>Created after removal of "/nfc/{uid} GET" from portfolio</description>
|
||||
<accepts>nfc_uid_GET.html</accepts>
|
||||
</rule>
|
||||
<rule id="2eac3350">
|
||||
<description>Created after removal of "API Reference" from portfolio</description>
|
||||
<accepts>API_Reference.html</accepts>
|
||||
</rule>
|
||||
</rules>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="API Reference" id="API_Reference">
|
||||
|
||||
<p>Start typing here...</p>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/check GET" id="check_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="GET" endpoint="/check"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/htmx/canEdit GET" id="htmx_canEdit_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="GET" endpoint="/htmx/canEdit"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/login POST" id="login_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="POST" endpoint="/login"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/project POST" id="project_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="POST" endpoint="/project"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/project/{id} GET" id="project_id_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="GET" endpoint="/project/{id}"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/project/{id} PATCH" id="project_id_PATCH">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="PATCH" endpoint="/project/{id}"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/projects GET" id="projects_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="GET" endpoint="/projects"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/projects PATCH" id="projects_PATCH">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="PATCH" endpoint="/projects"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/register POST" id="register_POST">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="POST" endpoint="/register"/>
|
||||
</topic>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE topic
|
||||
SYSTEM "https://resources.jetbrains.com/writerside/1.0/xhtml-entities.dtd">
|
||||
<topic xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://resources.jetbrains.com/writerside/1.0/topic.v2.xsd"
|
||||
title="/user/{uid} GET" id="user_uid_GET">
|
||||
|
||||
<api-endpoint openapi-path="../../openApi.json" method="GET" endpoint="/user/{uid}"/>
|
||||
</topic>
|
||||
@ -14,7 +14,6 @@ import (
|
||||
var Client *ent.Client
|
||||
|
||||
func DB() {
|
||||
log.Println("Connecting to database")
|
||||
err := *new(error)
|
||||
|
||||
port, parseError := strconv.ParseInt(os.Getenv("POSTGRES_PORT"), 10, 32)
|
||||
|
||||
@ -71,7 +71,7 @@ var (
|
||||
columnCheck sql.ColumnCheck
|
||||
)
|
||||
|
||||
// checkColumn checks if the column exists in the given table.
|
||||
// columnChecker checks if the column exists in the given table.
|
||||
func checkColumn(table, column string) error {
|
||||
initCheck.Do(func() {
|
||||
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
||||
|
||||
@ -4,7 +4,6 @@ package enttest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"portfolio/database/ent"
|
||||
// required by schema hooks.
|
||||
_ "portfolio/database/ent/runtime"
|
||||
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"portfolio/database/ent/team"
|
||||
"portfolio/database/ent/user"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@ -110,7 +109,7 @@ func (pq *ProjectQuery) QueryTeams() *TeamQuery {
|
||||
// First returns the first Project entity from the query.
|
||||
// Returns a *NotFoundError when no Project was found.
|
||||
func (pq *ProjectQuery) First(ctx context.Context) (*Project, error) {
|
||||
nodes, err := pq.Limit(1).All(setContextOp(ctx, pq.ctx, ent.OpQueryFirst))
|
||||
nodes, err := pq.Limit(1).All(setContextOp(ctx, pq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -133,7 +132,7 @@ func (pq *ProjectQuery) FirstX(ctx context.Context) *Project {
|
||||
// Returns a *NotFoundError when no Project ID was found.
|
||||
func (pq *ProjectQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = pq.Limit(1).IDs(setContextOp(ctx, pq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
if ids, err = pq.Limit(1).IDs(setContextOp(ctx, pq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@ -156,7 +155,7 @@ func (pq *ProjectQuery) FirstIDX(ctx context.Context) int {
|
||||
// Returns a *NotSingularError when more than one Project entity is found.
|
||||
// Returns a *NotFoundError when no Project entities are found.
|
||||
func (pq *ProjectQuery) Only(ctx context.Context) (*Project, error) {
|
||||
nodes, err := pq.Limit(2).All(setContextOp(ctx, pq.ctx, ent.OpQueryOnly))
|
||||
nodes, err := pq.Limit(2).All(setContextOp(ctx, pq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -184,7 +183,7 @@ func (pq *ProjectQuery) OnlyX(ctx context.Context) *Project {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (pq *ProjectQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = pq.Limit(2).IDs(setContextOp(ctx, pq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
if ids, err = pq.Limit(2).IDs(setContextOp(ctx, pq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@ -209,7 +208,7 @@ func (pq *ProjectQuery) OnlyIDX(ctx context.Context) int {
|
||||
|
||||
// All executes the query and returns a list of Projects.
|
||||
func (pq *ProjectQuery) All(ctx context.Context) ([]*Project, error) {
|
||||
ctx = setContextOp(ctx, pq.ctx, ent.OpQueryAll)
|
||||
ctx = setContextOp(ctx, pq.ctx, "All")
|
||||
if err := pq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -231,7 +230,7 @@ func (pq *ProjectQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if pq.ctx.Unique == nil && pq.path != nil {
|
||||
pq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, pq.ctx, ent.OpQueryIDs)
|
||||
ctx = setContextOp(ctx, pq.ctx, "IDs")
|
||||
if err = pq.Select(project.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -249,7 +248,7 @@ func (pq *ProjectQuery) IDsX(ctx context.Context) []int {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (pq *ProjectQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, pq.ctx, ent.OpQueryCount)
|
||||
ctx = setContextOp(ctx, pq.ctx, "Count")
|
||||
if err := pq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -267,7 +266,7 @@ func (pq *ProjectQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (pq *ProjectQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, pq.ctx, ent.OpQueryExist)
|
||||
ctx = setContextOp(ctx, pq.ctx, "Exist")
|
||||
switch _, err := pq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@ -665,7 +664,7 @@ func (pgb *ProjectGroupBy) Aggregate(fns ...AggregateFunc) *ProjectGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (pgb *ProjectGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, pgb.build.ctx, ent.OpQueryGroupBy)
|
||||
ctx = setContextOp(ctx, pgb.build.ctx, "GroupBy")
|
||||
if err := pgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -713,7 +712,7 @@ func (ps *ProjectSelect) Aggregate(fns ...AggregateFunc) *ProjectSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ps *ProjectSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ps.ctx, ent.OpQuerySelect)
|
||||
ctx = setContextOp(ctx, ps.ctx, "Select")
|
||||
if err := ps.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -5,6 +5,6 @@ package runtime
|
||||
// The schema-stitching logic is generated in portfolio/database/ent/runtime.go
|
||||
|
||||
const (
|
||||
Version = "v0.14.4" // Version of ent codegen.
|
||||
Sum = "h1:/DhDraSLXIkBhyiVoJeSshr4ZYi7femzhj6/TckzZuI=" // Sum of ent codegen.
|
||||
Version = "v0.13.1" // Version of ent codegen.
|
||||
Sum = "h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=" // Sum of ent codegen.
|
||||
)
|
||||
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"portfolio/database/ent/team"
|
||||
"portfolio/database/ent/user"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@ -110,7 +109,7 @@ func (tq *TeamQuery) QueryUsers() *UserQuery {
|
||||
// First returns the first Team entity from the query.
|
||||
// Returns a *NotFoundError when no Team was found.
|
||||
func (tq *TeamQuery) First(ctx context.Context) (*Team, error) {
|
||||
nodes, err := tq.Limit(1).All(setContextOp(ctx, tq.ctx, ent.OpQueryFirst))
|
||||
nodes, err := tq.Limit(1).All(setContextOp(ctx, tq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -133,7 +132,7 @@ func (tq *TeamQuery) FirstX(ctx context.Context) *Team {
|
||||
// Returns a *NotFoundError when no Team ID was found.
|
||||
func (tq *TeamQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = tq.Limit(1).IDs(setContextOp(ctx, tq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
if ids, err = tq.Limit(1).IDs(setContextOp(ctx, tq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@ -156,7 +155,7 @@ func (tq *TeamQuery) FirstIDX(ctx context.Context) int {
|
||||
// Returns a *NotSingularError when more than one Team entity is found.
|
||||
// Returns a *NotFoundError when no Team entities are found.
|
||||
func (tq *TeamQuery) Only(ctx context.Context) (*Team, error) {
|
||||
nodes, err := tq.Limit(2).All(setContextOp(ctx, tq.ctx, ent.OpQueryOnly))
|
||||
nodes, err := tq.Limit(2).All(setContextOp(ctx, tq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -184,7 +183,7 @@ func (tq *TeamQuery) OnlyX(ctx context.Context) *Team {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (tq *TeamQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = tq.Limit(2).IDs(setContextOp(ctx, tq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
if ids, err = tq.Limit(2).IDs(setContextOp(ctx, tq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@ -209,7 +208,7 @@ func (tq *TeamQuery) OnlyIDX(ctx context.Context) int {
|
||||
|
||||
// All executes the query and returns a list of Teams.
|
||||
func (tq *TeamQuery) All(ctx context.Context) ([]*Team, error) {
|
||||
ctx = setContextOp(ctx, tq.ctx, ent.OpQueryAll)
|
||||
ctx = setContextOp(ctx, tq.ctx, "All")
|
||||
if err := tq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -231,7 +230,7 @@ func (tq *TeamQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if tq.ctx.Unique == nil && tq.path != nil {
|
||||
tq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, tq.ctx, ent.OpQueryIDs)
|
||||
ctx = setContextOp(ctx, tq.ctx, "IDs")
|
||||
if err = tq.Select(team.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -249,7 +248,7 @@ func (tq *TeamQuery) IDsX(ctx context.Context) []int {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (tq *TeamQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, tq.ctx, ent.OpQueryCount)
|
||||
ctx = setContextOp(ctx, tq.ctx, "Count")
|
||||
if err := tq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -267,7 +266,7 @@ func (tq *TeamQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (tq *TeamQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, tq.ctx, ent.OpQueryExist)
|
||||
ctx = setContextOp(ctx, tq.ctx, "Exist")
|
||||
switch _, err := tq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@ -665,7 +664,7 @@ func (tgb *TeamGroupBy) Aggregate(fns ...AggregateFunc) *TeamGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (tgb *TeamGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, tgb.build.ctx, ent.OpQueryGroupBy)
|
||||
ctx = setContextOp(ctx, tgb.build.ctx, "GroupBy")
|
||||
if err := tgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -713,7 +712,7 @@ func (ts *TeamSelect) Aggregate(fns ...AggregateFunc) *TeamSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ts *TeamSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ts.ctx, ent.OpQuerySelect)
|
||||
ctx = setContextOp(ctx, ts.ctx, "Select")
|
||||
if err := ts.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@ import (
|
||||
"portfolio/database/ent/team"
|
||||
"portfolio/database/ent/user"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
@ -110,7 +109,7 @@ func (uq *UserQuery) QueryProjects() *ProjectQuery {
|
||||
// First returns the first User entity from the query.
|
||||
// Returns a *NotFoundError when no User was found.
|
||||
func (uq *UserQuery) First(ctx context.Context) (*User, error) {
|
||||
nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, ent.OpQueryFirst))
|
||||
nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -133,7 +132,7 @@ func (uq *UserQuery) FirstX(ctx context.Context) *User {
|
||||
// Returns a *NotFoundError when no User ID was found.
|
||||
func (uq *UserQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@ -156,7 +155,7 @@ func (uq *UserQuery) FirstIDX(ctx context.Context) int {
|
||||
// Returns a *NotSingularError when more than one User entity is found.
|
||||
// Returns a *NotFoundError when no User entities are found.
|
||||
func (uq *UserQuery) Only(ctx context.Context) (*User, error) {
|
||||
nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, ent.OpQueryOnly))
|
||||
nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -184,7 +183,7 @@ func (uq *UserQuery) OnlyX(ctx context.Context) *User {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (uq *UserQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@ -209,7 +208,7 @@ func (uq *UserQuery) OnlyIDX(ctx context.Context) int {
|
||||
|
||||
// All executes the query and returns a list of Users.
|
||||
func (uq *UserQuery) All(ctx context.Context) ([]*User, error) {
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryAll)
|
||||
ctx = setContextOp(ctx, uq.ctx, "All")
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -231,7 +230,7 @@ func (uq *UserQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if uq.ctx.Unique == nil && uq.path != nil {
|
||||
uq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryIDs)
|
||||
ctx = setContextOp(ctx, uq.ctx, "IDs")
|
||||
if err = uq.Select(user.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -249,7 +248,7 @@ func (uq *UserQuery) IDsX(ctx context.Context) []int {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (uq *UserQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryCount)
|
||||
ctx = setContextOp(ctx, uq.ctx, "Count")
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@ -267,7 +266,7 @@ func (uq *UserQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (uq *UserQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, uq.ctx, ent.OpQueryExist)
|
||||
ctx = setContextOp(ctx, uq.ctx, "Exist")
|
||||
switch _, err := uq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@ -665,7 +664,7 @@ func (ugb *UserGroupBy) Aggregate(fns ...AggregateFunc) *UserGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ugb *UserGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ugb.build.ctx, ent.OpQueryGroupBy)
|
||||
ctx = setContextOp(ctx, ugb.build.ctx, "GroupBy")
|
||||
if err := ugb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -713,7 +712,7 @@ func (us *UserSelect) Aggregate(fns ...AggregateFunc) *UserSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (us *UserSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, us.ctx, ent.OpQuerySelect)
|
||||
ctx = setContextOp(ctx, us.ctx, "Select")
|
||||
if err := us.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -4,13 +4,12 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"portfolio/api/types"
|
||||
"portfolio/database"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/ent/user"
|
||||
)
|
||||
|
||||
func GetLogin(ctx context.Context, U *types.LoginUser) (*ent.User, error) {
|
||||
func GetLogin(ctx context.Context, U *ent.User) (*ent.User, error) {
|
||||
u, err := database.Client.User.
|
||||
Query().
|
||||
Where(user.Email(U.Email)).
|
||||
|
||||
@ -85,7 +85,6 @@ func GetFullProjects(ctx context.Context) ([]*ent.Project, error) {
|
||||
func GetProjects(ctx context.Context) (ent.Projects, error) {
|
||||
|
||||
p, err := database.Client.Project.Query().
|
||||
Order(ent.Asc(project.FieldID)).
|
||||
All(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get projects: %w", err)
|
||||
|
||||
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"portfolio/api/types"
|
||||
"portfolio/database"
|
||||
"portfolio/database/ent"
|
||||
"portfolio/database/ent/user"
|
||||
@ -23,7 +22,7 @@ func GetUser(ctx context.Context, id int) (*ent.User, error) {
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func CreateUser(ctx context.Context, user types.RegisterUser) error {
|
||||
func CreateUser(ctx context.Context, user ent.User) error {
|
||||
|
||||
_, err := database.Client.User.
|
||||
Create().
|
||||
|
||||
@ -1,26 +1,36 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
portfolio:
|
||||
container_name: darius-portfolio-server
|
||||
build: .
|
||||
database:
|
||||
image: postgres:alpine
|
||||
restart: always
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "5432:5432"
|
||||
healthcheck:
|
||||
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
portfolio:
|
||||
build: .
|
||||
ports:
|
||||
- "4000:4000"
|
||||
- "4001:4001"
|
||||
restart: unless-stopped
|
||||
image: gitea.kleinsense.nl/dariusklein/portfolio:latest
|
||||
volumes:
|
||||
- ./backup:/web/assets/json
|
||||
image: docker.dariusklein.nl/portfolio:latest
|
||||
depends_on:
|
||||
database:
|
||||
condition: service_healthy
|
||||
|
||||
docs:
|
||||
container_name: darius-portfolio-docs
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./common/docs/Dockerfile
|
||||
ports:
|
||||
- "4002:80"
|
||||
restart: unless-stopped
|
||||
image: gitea.kleinsense.nl/dariusklein/portfolio-docs:latest
|
||||
image: docker.dariusklein.nl/portfolio-docs:latest
|
||||
|
||||
|
||||
38
go.mod
38
go.mod
@ -1,35 +1,31 @@
|
||||
module portfolio
|
||||
|
||||
go 1.24.0
|
||||
go 1.22.2
|
||||
|
||||
require (
|
||||
entgo.io/ent v0.14.4
|
||||
github.com/delaneyj/gomponents-iconify v0.0.20241016
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2
|
||||
entgo.io/ent v0.13.1
|
||||
github.com/delaneyj/gomponents-iconify v0.0.20231025
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/willoma/bulma-gomponents v0.13.0
|
||||
github.com/willoma/gomplements v0.8.0
|
||||
golang.org/x/crypto v0.38.0
|
||||
maragu.dev/gomponents v1.1.0
|
||||
maragu.dev/gomponents-htmx v0.6.1
|
||||
github.com/maragudk/gomponents v0.20.2
|
||||
github.com/maragudk/gomponents-htmx v0.5.0
|
||||
github.com/rs/cors v1.11.0
|
||||
github.com/willoma/bulma-gomponents v0.11.1
|
||||
github.com/willoma/gomplements v0.6.1
|
||||
golang.org/x/crypto v0.23.0
|
||||
)
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.32.1 // indirect
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
github.com/go-openapi/inflect v0.21.2 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/zclconf/go-cty v1.16.2 // indirect
|
||||
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/tools v0.33.0 // indirect
|
||||
github.com/zclconf/go-cty v1.14.2 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
)
|
||||
|
||||
66
go.sum
Normal file
66
go.sum
Normal file
@ -0,0 +1,66 @@
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 h1:GwdJbXydHCYPedeeLt4x/lrlIISQ4JTH1mRWuE5ZZ14=
|
||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43/go.mod h1:uj3pm+hUTVN/X5yfdBexHlZv+1Xu5u5ZbZx7+CDavNU=
|
||||
entgo.io/ent v0.13.1 h1:uD8QwN1h6SNphdCCzmkMN3feSUzNnVvV/WIkHKMbzOE=
|
||||
entgo.io/ent v0.13.1/go.mod h1:qCEmo+biw3ccBn9OyL4ZK5dfpwg++l1Gxwac5B1206A=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
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/delaneyj/gomponents-iconify v0.0.20231025 h1:GJU/KtZGoQ7CwIumei/fNITpMk0f0p7yYz4q/AVllss=
|
||||
github.com/delaneyj/gomponents-iconify v0.0.20231025/go.mod h1:ZjIP4npWKmVuJbvSjBTpzSl1QMimELl77gP/leg1bnI=
|
||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
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/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI=
|
||||
github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/maragudk/gomponents v0.20.2 h1:39FhnBNNCJzqNcD9Hmvp/5xj0otweFoyvVgFG6kXoy0=
|
||||
github.com/maragudk/gomponents v0.20.2/go.mod h1:nHkNnZL6ODgMBeJhrZjkMHVvNdoYsfmpKB2/hjdQ0Hg=
|
||||
github.com/maragudk/gomponents-htmx v0.5.0 h1:sWtiRa72YmymgxccjTNZW3h0akKsZvnhYke9RQiS9dk=
|
||||
github.com/maragudk/gomponents-htmx v0.5.0/go.mod h1:XgI7WE6ECWlyeVQ9Ix3R6aoKS4HtCSYtuQ4iH27GVDE=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
|
||||
github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/willoma/bulma-gomponents v0.11.1 h1:l5lPRGgxkv0SCMle5SNaF7YsVODoud9hXLGsyFo9IRc=
|
||||
github.com/willoma/bulma-gomponents v0.11.1/go.mod h1:1hkVH4/pPHtlPH5aIkS1pHMaerOV3SI1SDe8QXShHqA=
|
||||
github.com/willoma/gomplements v0.6.1 h1:JtOVIHFnMXqloflQHafVmsvtqlpf5b+d0Uj18KqrP1k=
|
||||
github.com/willoma/gomplements v0.6.1/go.mod h1:G/9prZq6jA7EZwIu0AF27HtULgAbUbOVp9oRhsunpkg=
|
||||
github.com/zclconf/go-cty v1.14.2 h1:kTG7lqmBou0Zkx35r6HJHUQTvaRPr5bIAf3AoHS0izI=
|
||||
github.com/zclconf/go-cty v1.14.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
86
go.work.sum
Normal file
86
go.work.sum
Normal file
@ -0,0 +1,86 @@
|
||||
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3 h1:ZSTrOEhiM5J5RFxEaFvMZVEAM1KvT1YzbEOwB2EAGjA=
|
||||
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/delaneyj/toolbelt v0.0.0-20230611200251-2df076bd1579 h1:lj+zHpYT5Xv69ZsEB6eTm1nZ/5S0NmwPip5zG8kO234=
|
||||
github.com/delaneyj/toolbelt v0.0.0-20230611200251-2df076bd1579/go.mod h1:XPp3P/k7PF1+gU3tFzemCcoIlJl45pRP2uIQ96pxBDQ=
|
||||
github.com/divan/num2words v0.0.0-20170904212200-57dba452f942 h1:fJ8/Lid8fF4i7Bwl7vWKvG2KeZzr3yU4qG6h/DPdXLU=
|
||||
github.com/divan/num2words v0.0.0-20170904212200-57dba452f942/go.mod h1:K88GQWK1aAiPMo9q2LZwyKBfEGnge7kmVVTUcZ61HSc=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
|
||||
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
|
||||
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
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/maragudk/is v0.1.0 h1:obq9anZNmOYcaNbeT0LMyjIexdNeYTw/TLAPD/BnZHA=
|
||||
github.com/maragudk/is v0.1.0/go.mod h1:W/r6+TpnISu+a88OLXQy5JQGCOhXQXXLD2e5b4xMn5c=
|
||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
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/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/smartystreets/goconvey v1.8.0 h1:Oi49ha/2MURE0WexF052Z0m+BNSGirfjg5RL+JXWq3w=
|
||||
github.com/smartystreets/goconvey v1.8.0/go.mod h1:EdX8jtrTIj26jmjCOVNMVSIYAtgexqXKHOXW2Dx9JLg=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
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/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
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/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg=
|
||||
k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
|
||||
modernc.org/libc v1.22.3 h1:D/g6O5ftAfavceqlLOFwaZuA5KYafKwmr30A6iSqoyY=
|
||||
modernc.org/libc v1.22.3/go.mod h1:MQrloYP209xa2zHome2a8HLiLm6k0UT8CoHpV74tOFw=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU=
|
||||
modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI=
|
||||
zombiezen.com/go/sqlite v0.13.0 h1:iEeyVqcm3fk5PCA8OQBhBxPnqrP4yYuVJBF+XZpSnOE=
|
||||
zombiezen.com/go/sqlite v0.13.0/go.mod h1:Ht/5Rg3Ae2hoyh1I7gbWtWAl89CNocfqeb/aAMTkJr4=
|
||||
39
main.go
39
main.go
@ -1,50 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/rs/cors"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"portfolio/api"
|
||||
"portfolio/database"
|
||||
"portfolio/web"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.Println("Starting application")
|
||||
// load .env in runtime environment
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
log.Fatalf(".env not found: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Catch interrupt
|
||||
cmd := make(chan os.Signal, 1)
|
||||
signal.Notify(cmd, os.Interrupt, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-cmd
|
||||
log.Println("Shutting down application")
|
||||
os.Exit(0)
|
||||
}()
|
||||
|
||||
//connect to database and migrate
|
||||
database.DB()
|
||||
|
||||
//init web routes
|
||||
webMux := web.Routes()
|
||||
webMux := web.WebRoutes()
|
||||
// Run web server
|
||||
webPort := os.Getenv("WEB_PORT")
|
||||
log.Printf("Starting API port [%s]", webPort)
|
||||
go func() {
|
||||
err := http.ListenAndServe(fmt.Sprintf(":%s", webPort), cors.AllowAll().Handler(webMux))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
go http.ListenAndServe(":4000", cors.AllowAll().Handler(webMux))
|
||||
|
||||
c := cors.New(cors.Options{
|
||||
AllowedOrigins: []string{"http://localhost:4000", "https://*.dariusklein.nl", "https://*.portfolio.dariusklein.nl", "https://dariusklein.nl"},
|
||||
@ -56,18 +36,13 @@ func main() {
|
||||
http.MethodPatch,
|
||||
http.MethodDelete,
|
||||
},
|
||||
AllowedHeaders: []string{"Authorization", "Content-Type", "*"},
|
||||
AllowedHeaders: []string{"*"},
|
||||
AllowCredentials: true,
|
||||
Debug: true,
|
||||
})
|
||||
|
||||
//init api routes
|
||||
apiMux := api.Routes()
|
||||
apiMux := api.ApiRoutes()
|
||||
//run api server
|
||||
apiPort := os.Getenv("API_PORT")
|
||||
log.Printf("Starting API port [%s]", apiPort)
|
||||
err = http.ListenAndServe(fmt.Sprintf(":%s", apiPort), c.Handler(apiMux))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
http.ListenAndServe(":4001", c.Handler(apiMux))
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -1,10 +1,10 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
g "github.com/maragudk/gomponents"
|
||||
hx "github.com/maragudk/gomponents-htmx"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
b "github.com/willoma/bulma-gomponents"
|
||||
g "maragu.dev/gomponents"
|
||||
hx "maragu.dev/gomponents-htmx"
|
||||
. "maragu.dev/gomponents/html"
|
||||
)
|
||||
|
||||
func Edit() g.Node {
|
||||
|
||||
@ -2,9 +2,9 @@ package components
|
||||
|
||||
import (
|
||||
"github.com/delaneyj/gomponents-iconify/iconify/mdi"
|
||||
g "github.com/maragudk/gomponents"
|
||||
b "github.com/willoma/bulma-gomponents"
|
||||
e "github.com/willoma/gomplements"
|
||||
g "maragu.dev/gomponents"
|
||||
)
|
||||
|
||||
func Email(valid bool, invalid bool, color e.Element) e.Element {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
g "github.com/maragudk/gomponents"
|
||||
hx "github.com/maragudk/gomponents-htmx"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
b "github.com/willoma/bulma-gomponents"
|
||||
g "maragu.dev/gomponents"
|
||||
hx "maragu.dev/gomponents-htmx"
|
||||
. "maragu.dev/gomponents/html"
|
||||
)
|
||||
|
||||
var BaseUrl = "https://api.portfolio.dariusklein.nl"
|
||||
@ -12,7 +12,7 @@ var BaseUrl = "https://api.portfolio.dariusklein.nl"
|
||||
// todo var BaseUrl = "http://localhost:4001"
|
||||
|
||||
func Login() g.Node {
|
||||
return Form(hx.Post(BaseUrl+"/login"), //https://api.portfolio.dariusklein.nl/login
|
||||
return FormEl(hx.Post(BaseUrl+"/login"), //https://api.portfolio.dariusklein.nl/login
|
||||
Class("max-w-xl m-auto py-32"),
|
||||
b.Box(
|
||||
Email(false, false, nil),
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package components
|
||||
|
||||
import (
|
||||
g "github.com/maragudk/gomponents"
|
||||
b "github.com/willoma/bulma-gomponents"
|
||||
e "github.com/willoma/gomplements"
|
||||
g "maragu.dev/gomponents"
|
||||
)
|
||||
|
||||
func Navbar() g.Node {
|
||||
@ -22,6 +22,15 @@ func Navbar() g.Node {
|
||||
b.NavbarAHref("/", "Home"),
|
||||
b.NavbarAHref("/about", "Wie ben ik"),
|
||||
b.NavbarAHref("/projects", "projecten"),
|
||||
b.NavbarDropdown(
|
||||
"placeholder",
|
||||
b.Hoverable,
|
||||
b.NavbarAHref("#1", "item 1"),
|
||||
b.NavbarAHref("#2", "item 2"),
|
||||
b.NavbarAHref("#3", "item 3"),
|
||||
b.NavbarDivider(),
|
||||
b.NavbarAHref("#4", "divided item"),
|
||||
),
|
||||
),
|
||||
b.NavbarEnd(
|
||||
b.NavbarItem(
|
||||
|
||||
@ -2,10 +2,10 @@ package components
|
||||
|
||||
import (
|
||||
"github.com/delaneyj/gomponents-iconify/iconify/mdi"
|
||||
g "github.com/maragudk/gomponents"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
b "github.com/willoma/bulma-gomponents"
|
||||
e "github.com/willoma/gomplements"
|
||||
g "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/html"
|
||||
"portfolio/database/ent"
|
||||
"strconv"
|
||||
)
|
||||
@ -56,18 +56,23 @@ func EditProject(project *ent.Project) g.Node {
|
||||
b.ImgSq64,
|
||||
),
|
||||
),
|
||||
b.Textarea(strconv.Itoa(project.ID), b.Rows(1), e.Name("project_id"), e.ReadOnly(true)),
|
||||
Input(Type("hidden"), Value(strconv.Itoa(project.ID)), Name("project_id")),
|
||||
//b.Label("ID: "+strconv.Itoa(project.ID), Name("project_id")),
|
||||
b.Label("Name"),
|
||||
b.Textarea(project.Name, b.Rows(1), e.Name("project_name")),
|
||||
b.Textarea(project.Name, b.Rows(1), Name("project_name")),
|
||||
b.Subtitle(
|
||||
6,
|
||||
b.Label("Repo"),
|
||||
b.Textarea(project.URL, b.Rows(1), e.Name("project_repo")),
|
||||
b.Textarea(project.URL, b.Rows(1), Name("project_repo")),
|
||||
b.Label("Docs"),
|
||||
b.Textarea(project.DocURL, b.Rows(1), e.Name("project_docs"))),
|
||||
b.Textarea(project.DocURL, b.Rows(1), Name("project_docs"))),
|
||||
),
|
||||
b.Content(
|
||||
b.Textarea(project.Description, e.Name("project_description")),
|
||||
b.Textarea(project.Description, Name("project_description")),
|
||||
),
|
||||
|
||||
//b.CardFooter(
|
||||
//Save(),
|
||||
//),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
g "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/html"
|
||||
g "github.com/maragudk/gomponents"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -17,10 +17,5 @@ func AboutPageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func createAboutBody(w http.ResponseWriter, r *http.Request) g.Node {
|
||||
|
||||
return Body(
|
||||
IFrame(
|
||||
Src("/assets/pdf/cv.pdf"),
|
||||
Class("h-screen w-screen"),
|
||||
),
|
||||
)
|
||||
return Body()
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
g "github.com/maragudk/gomponents"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
b "github.com/willoma/bulma-gomponents"
|
||||
e "github.com/willoma/gomplements"
|
||||
g "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/html"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
@ -26,7 +26,7 @@ func createHomeBody(w http.ResponseWriter, r *http.Request) g.Node {
|
||||
b.MediaLeft(
|
||||
Figure,
|
||||
b.ImageImg("assets/images/darius_circle_noEdge_crop_upscayl_1x_realesrgan-x4plus-anime.png",
|
||||
b.OnImg(e.Class("object-scale-down grayscale "+
|
||||
b.OnImg(Class("object-scale-down grayscale "+
|
||||
"max-h-[calc(25vh_-_3.75rem)] "+
|
||||
"sm:max-h-[calc(40vh_-_3.75rem)] "+
|
||||
"md:max-h-[calc(60vh_-_3.75rem)] "+
|
||||
@ -37,7 +37,7 @@ func createHomeBody(w http.ResponseWriter, r *http.Request) g.Node {
|
||||
b.Section(
|
||||
b.Margin(100),
|
||||
e.H1("Darius Klein",
|
||||
e.Class("title backdrop-blur "+
|
||||
Class("title backdrop-blur "+
|
||||
"text-2xl "+
|
||||
"sm:text-4xl "+
|
||||
"md:text-6xl "+
|
||||
@ -45,7 +45,7 @@ func createHomeBody(w http.ResponseWriter, r *http.Request) g.Node {
|
||||
),
|
||||
e.H2(
|
||||
"Backend developer die zelf zijn servers kan opzetten.",
|
||||
e.Class("subtitle backdrop-blur"),
|
||||
Class("subtitle backdrop-blur"),
|
||||
),
|
||||
|
||||
b.ButtonAHref("/projects", "Mijn projecten.", b.Primary, b.Centered, b.Large),
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
g "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/html"
|
||||
g "github.com/maragudk/gomponents"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
"net/http"
|
||||
"portfolio/web/components"
|
||||
)
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
g "maragu.dev/gomponents"
|
||||
c "maragu.dev/gomponents/components"
|
||||
. "maragu.dev/gomponents/html"
|
||||
g "github.com/maragudk/gomponents"
|
||||
c "github.com/maragudk/gomponents/components"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
"portfolio/web/components"
|
||||
)
|
||||
|
||||
|
||||
@ -2,8 +2,8 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
g "maragu.dev/gomponents"
|
||||
. "maragu.dev/gomponents/html"
|
||||
g "github.com/maragudk/gomponents"
|
||||
. "github.com/maragudk/gomponents/html"
|
||||
"net/http"
|
||||
"portfolio/database/query"
|
||||
"portfolio/web/components"
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"portfolio/web/handlers"
|
||||
)
|
||||
|
||||
func Routes() *http.ServeMux {
|
||||
log.Println("Setup web routes")
|
||||
func WebRoutes() *http.ServeMux {
|
||||
// Create a new request multiplexer
|
||||
// Take incoming requests and dispatch them to the matching webHandler
|
||||
mux := http.NewServeMux()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user