add graphql schema
This commit is contained in:
parent
4f9c6b67df
commit
49c8dd355a
5
go.mod
5
go.mod
|
@ -4,6 +4,7 @@ go 1.16
|
|||
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.13.0
|
||||
github.com/agnivade/levenshtein v1.1.0 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/gin-contrib/cors v1.3.1
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
|
@ -14,5 +15,9 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/sethvargo/go-password v0.2.0
|
||||
github.com/sirupsen/logrus v1.8.0
|
||||
github.com/vektah/gqlparser/v2 v2.1.0
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
|
14
go.sum
14
go.sum
|
@ -4,8 +4,11 @@ github.com/99designs/gqlgen v0.13.0/go.mod h1:NV130r6f4tpRWuAI+zsrSdooO/eWUv+Gyy
|
|||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
|
||||
github.com/agnivade/levenshtein v1.1.0 h1:n6qGwyHG61v3ABce1rPVZklEYRT8NFpCMrpZdBUbYGM=
|
||||
github.com/agnivade/levenshtein v1.1.0/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
|
@ -16,6 +19,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
|
||||
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
|
@ -212,8 +217,9 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b h1:lAZ0/chPUDWwjqosYR0X4M490zQhMsiJ4K3DbA7o+3g=
|
||||
golang.org/x/sys v0.0.0-20210218155724-8ebf48af031b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b h1:ggRgirZABFolTmi3sn6Ivd9SipZwLedQ5wR0aAKnFxU=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
@ -228,8 +234,9 @@ golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBn
|
|||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
|
@ -261,8 +268,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
|
|||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#!/bin/sh
|
||||
cd ./internal/graphql
|
||||
go get -u github.com/99designs/gqlgen
|
||||
go run github.com/99designs/gqlgen
|
||||
go mod tidy
|
||||
cd ../..
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
// Code generated by github.com/99designs/gqlgen, DO NOT EDIT.
|
||||
|
||||
package generated
|
||||
|
||||
import (
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
|
||||
)
|
||||
|
||||
type ProfessionList struct {
|
||||
Total int `json:"total"`
|
||||
Items []*models.Profession `json:"items"`
|
||||
}
|
||||
|
||||
type QualificationList struct {
|
||||
Total int `json:"total"`
|
||||
Items []*models.Qualification `json:"items"`
|
||||
}
|
||||
|
||||
type QuestionList struct {
|
||||
Total int `json:"total"`
|
||||
Items []*models.Question `json:"items"`
|
||||
}
|
||||
|
||||
type UserList struct {
|
||||
Total int `json:"total"`
|
||||
Items []*models.User `json:"items"`
|
||||
}
|
|
@ -10,4 +10,58 @@ resolver:
|
|||
filename: resolvers/resolver.go
|
||||
package: resolvers
|
||||
type: Resolver
|
||||
struct_tag: gqlgen
|
||||
struct_tag: gqlgen
|
||||
models:
|
||||
ID:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Int
|
||||
- github.com/99designs/gqlgen/graphql.Int64
|
||||
- github.com/99designs/gqlgen/graphql.Int32
|
||||
Role:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Role
|
||||
User:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.User
|
||||
UserFilter:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserFilter
|
||||
UserInput:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserInput
|
||||
UpdateManyUsersInput:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserInput
|
||||
Profession:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Profession
|
||||
ProfessionFilter:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.ProfessionFilter
|
||||
ProfessionInput:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.ProfessionInput
|
||||
Qualification:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Qualification
|
||||
QualificationFilter:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QualificationFilter
|
||||
QualificationFilterOr:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QualificationFilterOr
|
||||
QualificationInput:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QualificationInput
|
||||
Answer:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Answer
|
||||
Question:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Question
|
||||
QuestionFilter:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QuestionFilter
|
||||
QuestionInput:
|
||||
model:
|
||||
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QuestionInput
|
|
@ -0,0 +1,32 @@
|
|||
package resolvers
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) CreateProfession(ctx context.Context, input models.ProfessionInput) (*models.Profession, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateProfession(ctx context.Context, id int, input models.ProfessionInput) (*models.Profession, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) DeleteProfessions(ctx context.Context, ids []int) ([]*models.Profession, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Professions(ctx context.Context, filter *models.ProfessionFilter, limit *int, offset *int, sort []string) (*generated.ProfessionList, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Profession(ctx context.Context, id *int, slug *string) (*models.Profession, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package resolvers
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) CreateQualification(ctx context.Context, input models.QualificationInput) (*models.Qualification, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateQualification(ctx context.Context, id int, input models.QualificationInput) (*models.Qualification, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) DeleteQualifications(ctx context.Context, ids []int) ([]*models.Qualification, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Qualifications(ctx context.Context, filter *models.QualificationFilter, limit *int, offset *int, sort []string) (*generated.QualificationList, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Qualification(ctx context.Context, id *int, slug *string) (*models.Qualification, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package resolvers
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) CreateQuestion(ctx context.Context, input models.QuestionInput) (*models.Question, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateQuestion(ctx context.Context, id int, input models.QuestionInput) (*models.Question, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) DeleteQuestions(ctx context.Context, ids []int) ([]*models.Question, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) GenerateTest(ctx context.Context, qualificationIDs []int, limit *int) ([]*models.Question, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Questions(ctx context.Context, filter *models.QuestionFilter, limit *int, offset *int, sort []string) (*generated.QuestionList, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *questionResolver) Qualification(ctx context.Context, obj *models.Question) (*models.Qualification, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package resolvers
|
||||
|
||||
import "github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
|
||||
|
||||
// This file will not be regenerated automatically.
|
||||
//
|
||||
// It serves as dependency injection for your app, add any dependencies you require here.
|
||||
|
||||
type Resolver struct{}
|
||||
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
type questionResolver struct{ *Resolver }
|
||||
|
||||
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }
|
||||
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
||||
func (r *Resolver) Question() generated.QuestionResolver { return &questionResolver{r} }
|
|
@ -0,0 +1,44 @@
|
|||
package resolvers
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
|
||||
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) CreateUser(ctx context.Context, input models.UserInput) (*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateUser(ctx context.Context, id int, input models.UserInput) (*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateManyUsers(ctx context.Context, ids []int, input models.UserInput) ([]*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) DeleteUsers(ctx context.Context, ids []int) ([]*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *mutationResolver) SignIn(ctx context.Context, email string, password string, staySignedIn *bool) (*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Users(ctx context.Context, filter *models.UserFilter, limit *int, offset *int, sort []string) (*generated.UserList, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) User(ctx context.Context, id int) (*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
||||
|
||||
func (r *queryResolver) Me(ctx context.Context) (*models.User, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
directive @goField(
|
||||
forceResolver: Boolean
|
||||
name: String
|
||||
) on INPUT_FIELD_DEFINITION | FIELD_DEFINITION
|
||||
|
||||
directive @authenticated(yes: Boolean!) on FIELD_DEFINITION
|
||||
directive @hasRole(role: Role!) on FIELD_DEFINITION
|
|
@ -0,0 +1,61 @@
|
|||
type Profession {
|
||||
id: ID!
|
||||
slug: String!
|
||||
name: String!
|
||||
description: String
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
type ProfessionList {
|
||||
total: Int!
|
||||
items: [Profession!]
|
||||
}
|
||||
|
||||
input ProfessionInput {
|
||||
name: String
|
||||
description: String
|
||||
}
|
||||
|
||||
input ProfessionFilter {
|
||||
id: [ID!]
|
||||
idNEQ: [ID!]
|
||||
|
||||
slug: [String!]
|
||||
slugNEQ: [String!]
|
||||
|
||||
name: [String!]
|
||||
nameNEQ: [String!]
|
||||
nameIEQ: String
|
||||
nameMATCH: String
|
||||
|
||||
descriptionIEQ: String
|
||||
descriptionMATCH: String
|
||||
|
||||
createdAt: Time
|
||||
createdAtGT: Time
|
||||
createdAtGTE: Time
|
||||
createdAtLT: Time
|
||||
createdAtLTE: Time
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
professions(
|
||||
filter: ProfessionFilter
|
||||
limit: Int
|
||||
offset: Int
|
||||
sort: [String!]
|
||||
): ProfessionList!
|
||||
profession(id: Int, slug: String): Profession
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createProfession(input: ProfessionInput!): Profession
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
updateProfession(id: ID!, input: ProfessionInput!): Profession
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
deleteProfessions(ids: [ID!]!): [Profession!]
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
type Qualification {
|
||||
id: ID!
|
||||
slug: String!
|
||||
name: String!
|
||||
code: String!
|
||||
formula: String
|
||||
description: String
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
type QualificationList {
|
||||
total: Int!
|
||||
items: [Qualification!]
|
||||
}
|
||||
|
||||
input QualificationInput {
|
||||
name: String
|
||||
description: String
|
||||
code: String
|
||||
formula: String
|
||||
associateProfession: [Int!]
|
||||
dissociateProfession: [Int!]
|
||||
}
|
||||
|
||||
input QualificationFilterOr {
|
||||
nameMatch: String
|
||||
nameIEQ: String
|
||||
|
||||
codeMatch: String
|
||||
codeIEQ: String
|
||||
}
|
||||
|
||||
input QualificationFilter {
|
||||
id: [ID!]
|
||||
idNEQ: [ID!]
|
||||
|
||||
slug: [String!]
|
||||
slugNEQ: [String!]
|
||||
|
||||
formula: [String!]
|
||||
formulaNEQ: [String!]
|
||||
|
||||
name: [String!]
|
||||
nameNEQ: [String!]
|
||||
nameIEQ: String
|
||||
nameMATCH: String
|
||||
|
||||
code: [String!]
|
||||
codeNEQ: [String!]
|
||||
codeIEQ: String
|
||||
codeMATCH: String
|
||||
|
||||
descriptionIEQ: String
|
||||
descriptionMATCH: String
|
||||
|
||||
professionID: [Int!]
|
||||
|
||||
createdAt: Time
|
||||
createdAtGT: Time
|
||||
createdAtGTE: Time
|
||||
createdAtLT: Time
|
||||
createdAtLTE: Time
|
||||
|
||||
or: QualificationFilterOr
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
qualifications(
|
||||
filter: QualificationFilter
|
||||
limit: Int
|
||||
offset: Int
|
||||
sort: [String!]
|
||||
): QualificationList!
|
||||
qualification(id: Int, slug: String): Qualification
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createQualification(input: QualificationInput!): Qualification
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
updateQualification(id: ID!, input: QualificationInput!): Qualification
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
deleteQualifications(ids: [ID!]!): [Qualification!]
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
enum Answer {
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
}
|
||||
|
||||
type Question {
|
||||
id: ID!
|
||||
from: String
|
||||
content: String!
|
||||
explanation: String
|
||||
correctAnswer: Answer!
|
||||
image: String
|
||||
answerA: Answer
|
||||
answerAImage: String
|
||||
answerB: Answer
|
||||
answerBImage: String
|
||||
answerC: Answer
|
||||
answerCImage: String
|
||||
answerD: Answer
|
||||
answerDImage: String
|
||||
qualification: Qualification @goField(forceResolver: true)
|
||||
createdAt: Time!
|
||||
updatedAt: Time!
|
||||
}
|
||||
|
||||
type QuestionList {
|
||||
total: Int!
|
||||
items: [Question!]
|
||||
}
|
||||
|
||||
input QuestionInput {
|
||||
content: String
|
||||
from: String
|
||||
explanation: String
|
||||
correctAnswer: Answer
|
||||
qualificationID: Int
|
||||
image: Upload
|
||||
deleteImage: Boolean
|
||||
answerA: Answer
|
||||
answerAImage: Upload
|
||||
deleteAnswerAImage: Boolean
|
||||
answerB: Answer
|
||||
answerBImage: Upload
|
||||
deleteAnswerBImage: Boolean
|
||||
answerC: Answer
|
||||
answerCImage: Upload
|
||||
deleteAnswerCImage: Boolean
|
||||
answerD: Answer
|
||||
answerDImage: Upload
|
||||
deleteAnswerDImage: Boolean
|
||||
}
|
||||
|
||||
input QuestionFilter {
|
||||
id: [ID!]
|
||||
idNEQ: [ID!]
|
||||
|
||||
from: [String!]
|
||||
|
||||
contentIEQ: String
|
||||
contentMATCH: String
|
||||
|
||||
qualificationID: [Int!]
|
||||
qualificationIDNEQ: [Int!]
|
||||
qualificationFilter: QualificationFilter
|
||||
|
||||
createdAt: Time
|
||||
createdAtGT: Time
|
||||
createdAtGTE: Time
|
||||
createdAtLT: Time
|
||||
createdAtLTE: Time
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
questions(
|
||||
filter: QuestionFilter
|
||||
limit: Int
|
||||
offset: Int
|
||||
sort: [String!]
|
||||
): QuestionList! @authenticated(yes: true) @hasRole(role: ADMIN)
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createQuestion(input: QuestionInput!): Question
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
updateQuestion(id: ID!, input: QuestionInput!): Question
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
deleteQuestions(ids: [ID!]!): [Question!]
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
generateTest(qualificationIDs: [ID!]!, limit: Int): [Question!]
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
scalar Time
|
||||
scalar Upload
|
|
@ -0,0 +1,85 @@
|
|||
enum Role {
|
||||
ADMIN
|
||||
USER
|
||||
}
|
||||
|
||||
type User {
|
||||
id: ID!
|
||||
displayName: String!
|
||||
role: Role!
|
||||
email: String!
|
||||
activated: Boolean!
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
type UserList {
|
||||
total: Int!
|
||||
items: [User!]
|
||||
}
|
||||
|
||||
input UserInput {
|
||||
displayName: String
|
||||
password: String
|
||||
email: String
|
||||
role: Role
|
||||
activated: Boolean
|
||||
}
|
||||
|
||||
input UpdateManyUsersInput {
|
||||
role: Role
|
||||
activated: Boolean
|
||||
}
|
||||
|
||||
input UserFilter {
|
||||
id: [ID!]
|
||||
idNEQ: [ID!]
|
||||
|
||||
activated: Boolean
|
||||
|
||||
displayName: [String!]
|
||||
displayNameNEQ: [String!]
|
||||
displayNameIEQ: String
|
||||
displayNameMATCH: String
|
||||
|
||||
email: [String!]
|
||||
emailNEQ: [String!]
|
||||
emailIEQ: String
|
||||
emailMATCH: String
|
||||
|
||||
role: [Role!]
|
||||
roleNEQ: [Role!]
|
||||
|
||||
createdAt: Time
|
||||
createdAtGT: Time
|
||||
createdAtGTE: Time
|
||||
createdAtLT: Time
|
||||
createdAtLTE: Time
|
||||
}
|
||||
|
||||
extend type Query {
|
||||
users(
|
||||
filter: UserFilter
|
||||
limit: Int
|
||||
offset: Int
|
||||
sort: [String!]
|
||||
): UserList! @authenticated(yes: true) @hasRole(role: ADMIN)
|
||||
user(id: Int!): User @authenticated(yes: true) @hasRole(role: ADMIN)
|
||||
me: User
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createUser(input: UserInput!): User
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
updateUser(id: ID!, input: UserInput!): User
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
updateManyUsers(ids: [ID!]!, input: UpdateManyUsersInput!): [User!]
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
deleteUsers(ids: [ID!]!): [User!]
|
||||
@authenticated(yes: true)
|
||||
@hasRole(role: ADMIN)
|
||||
signIn(email: String!, password: String!, staySignedIn: Boolean): User
|
||||
@authenticated(yes: false)
|
||||
}
|
|
@ -47,12 +47,10 @@ func (input *ProfessionInput) IsEmpty() bool {
|
|||
|
||||
func (input *ProfessionInput) Sanitize() *ProfessionInput {
|
||||
if input.Name != nil {
|
||||
trimmed := strings.TrimSpace(*input.Name)
|
||||
input.Name = &trimmed
|
||||
*input.Name = strings.TrimSpace(*input.Name)
|
||||
}
|
||||
if input.Description != nil {
|
||||
trimmed := strings.TrimSpace(*input.Description)
|
||||
input.Description = &trimmed
|
||||
*input.Description = strings.TrimSpace(*input.Description)
|
||||
}
|
||||
|
||||
return input
|
||||
|
|
|
@ -66,20 +66,16 @@ func (input *QualificationInput) IsEmpty() bool {
|
|||
|
||||
func (input *QualificationInput) Sanitize() *QualificationInput {
|
||||
if input.Name != nil {
|
||||
trimmed := strings.TrimSpace(*input.Name)
|
||||
input.Name = &trimmed
|
||||
*input.Name = strings.TrimSpace(*input.Name)
|
||||
}
|
||||
if input.Description != nil {
|
||||
trimmed := strings.TrimSpace(*input.Description)
|
||||
input.Description = &trimmed
|
||||
*input.Description = strings.TrimSpace(*input.Description)
|
||||
}
|
||||
if input.Code != nil {
|
||||
trimmed := strings.TrimSpace(*input.Code)
|
||||
input.Code = &trimmed
|
||||
*input.Code = strings.TrimSpace(*input.Code)
|
||||
}
|
||||
if input.Formula != nil {
|
||||
trimmed := strings.TrimSpace(*input.Formula)
|
||||
input.Formula = &trimmed
|
||||
*input.Formula = strings.TrimSpace(*input.Formula)
|
||||
}
|
||||
|
||||
return input
|
||||
|
@ -155,6 +151,9 @@ type QualificationFilter struct {
|
|||
Slug []string `json:"slug" xml:"slug" gqlgen:"slug"`
|
||||
SlugNEQ []string `json:"slugNEQ" xml:"slugNEQ" gqlgen:"slugNEQ"`
|
||||
|
||||
Formula []string `gqlgen:"formula" json:"formula" xml:"formula"`
|
||||
FormulaNEQ []string `json:"formulaNEQ" xml:"formulaNEQ" gqlgen:"formulaNEQ"`
|
||||
|
||||
Name []string `gqlgen:"name" json:"name" xml:"name"`
|
||||
NameNEQ []string `json:"nameNEQ" xml:"nameNEQ" gqlgen:"nameNEQ"`
|
||||
NameMATCH string `json:"nameMATCH" xml:"nameMATCH" gqlgen:"nameMATCH"`
|
||||
|
@ -165,9 +164,6 @@ type QualificationFilter struct {
|
|||
CodeMATCH string `json:"codeMATCH" xml:"codeMATCH" gqlgen:"codeMATCH"`
|
||||
CodeIEQ string `gqlgen:"codeIEQ" json:"codeIEQ" xml:"codeIEQ"`
|
||||
|
||||
Formula []string `gqlgen:"formula" json:"formula" xml:"formula"`
|
||||
FormulaNEQ []string `json:"formulaNEQ" xml:"formulaNEQ" gqlgen:"formulaNEQ"`
|
||||
|
||||
DescriptionMATCH string `gqlgen:"descriptionMATCH" json:"descriptionMATCH" xml:"descriptionMATCH"`
|
||||
DescriptionIEQ string `json:"descriptionIEQ" xml:"descriptionIEQ" gqlgen:"descriptionIEQ"`
|
||||
|
||||
|
|
|
@ -83,16 +83,13 @@ func (input *QuestionInput) IsEmpty() bool {
|
|||
|
||||
func (input *QuestionInput) Sanitize() *QuestionInput {
|
||||
if input.Content != nil {
|
||||
trimmed := strings.TrimSpace(*input.Content)
|
||||
input.Content = &trimmed
|
||||
*input.Content = strings.TrimSpace(*input.Content)
|
||||
}
|
||||
if input.From != nil {
|
||||
trimmed := strings.TrimSpace(*input.From)
|
||||
input.From = &trimmed
|
||||
*input.From = strings.TrimSpace(*input.From)
|
||||
}
|
||||
if input.Explanation != nil {
|
||||
trimmed := strings.TrimSpace(*input.Explanation)
|
||||
input.Explanation = &trimmed
|
||||
*input.Explanation = strings.TrimSpace(*input.Explanation)
|
||||
}
|
||||
|
||||
return input
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
type Role string
|
||||
|
||||
const (
|
||||
RoleUser Role = "user"
|
||||
RoleAdmin Role = "admin"
|
||||
RoleUser Role = "user"
|
||||
)
|
||||
|
||||
func (role Role) IsValid() bool {
|
||||
|
|
|
@ -68,6 +68,20 @@ func (input *UserInput) IsEmpty() bool {
|
|||
input.Activated == nil
|
||||
}
|
||||
|
||||
func (input *UserInput) Sanitize() *UserInput {
|
||||
if input.DisplayName != nil {
|
||||
*input.DisplayName = strings.TrimSpace(*input.DisplayName)
|
||||
}
|
||||
if input.Password != nil {
|
||||
*input.Password = strings.ToLower(strings.TrimSpace(*input.Password))
|
||||
}
|
||||
if input.Email != nil {
|
||||
*input.Email = strings.ToLower(strings.TrimSpace(*input.Email))
|
||||
}
|
||||
|
||||
return input
|
||||
}
|
||||
|
||||
func (input *UserInput) ToUser() *User {
|
||||
u := &User{
|
||||
Activated: input.Activated,
|
||||
|
@ -87,25 +101,6 @@ func (input *UserInput) ToUser() *User {
|
|||
return u
|
||||
}
|
||||
|
||||
func (input *UserInput) Sanitize() *UserInput {
|
||||
if input.DisplayName != nil {
|
||||
trimmed := strings.TrimSpace(*input.DisplayName)
|
||||
input.DisplayName = &trimmed
|
||||
}
|
||||
|
||||
if input.Password != nil {
|
||||
sanitized := strings.ToLower(strings.TrimSpace(*input.Password))
|
||||
input.Password = &sanitized
|
||||
}
|
||||
|
||||
if input.Email != nil {
|
||||
sanitized := strings.ToLower(strings.TrimSpace(*input.Email))
|
||||
input.Email = &sanitized
|
||||
}
|
||||
|
||||
return input
|
||||
}
|
||||
|
||||
func (input *UserInput) ApplyUpdate(q *orm.Query) (*orm.Query, error) {
|
||||
if !input.IsEmpty() {
|
||||
if input.DisplayName != nil {
|
||||
|
|
Reference in New Issue