Merge pull request #21 from zdam-egzamin-zawodowy/refactor

refactor
This commit is contained in:
Dawid Wysokiński 2021-07-14 07:14:25 +02:00 committed by GitHub
commit 368e212a4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 718 additions and 710 deletions

2
go.mod
View File

@ -24,8 +24,6 @@ require (
github.com/sethvargo/go-password v0.2.0
github.com/sirupsen/logrus v1.8.1
github.com/vektah/gqlparser/v2 v2.1.0
github.com/vmihailenco/msgpack/v5 v5.3.1 // indirect
go.opentelemetry.io/otel v0.20.0 // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
)

16
go.sum
View File

@ -46,10 +46,7 @@ github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmC
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-pg/pg/v10 v10.9.1 h1:kU4t84zWGGaU0Qsu49FbNtToUVrlSTkNOngW8aQmwvk=
github.com/go-pg/pg/v10 v10.9.1/go.mod h1:rgmTPgHgl5EN2CNKKoMwC7QT62t8BqsdpEkUQuiZMQs=
github.com/go-pg/pg/v10 v10.10.1 h1:82lLX4KGs2wOFOvVVIICoU0Si1fLu6Aitniu73HaDuM=
github.com/go-pg/pg/v10 v10.10.1/go.mod h1:EmoJGYErc+stNN/1Jf+o4csXuprjxcRztBnn6cHe38E=
github.com/go-pg/pg/v10 v10.10.2 h1:8G2DdKrB3/0nRIlpur0HySEWBJnHYUByiC0ko4XzE8w=
github.com/go-pg/pg/v10 v10.10.2/go.mod h1:EmoJGYErc+stNN/1Jf+o4csXuprjxcRztBnn6cHe38E=
github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU=
@ -202,26 +199,15 @@ github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
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=
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g=
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
go.opentelemetry.io/otel/metric v0.20.0 h1:4kzhXFP+btKm4jwxpjIqjs41A7MakRFUS86bqLHTIw8=
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
go.opentelemetry.io/otel/oteltest v0.20.0 h1:HiITxCawalo5vQzdHfKeZurV8x7ljcqAgiWzF6Vaeaw=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
go.opentelemetry.io/otel/trace v0.20.0 h1:1DL6EXUdcg95gukhuRRvLDO/4X5THh/5dIV52lqtnbw=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -261,8 +247,6 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

View File

@ -25,22 +25,17 @@ func (opts Metadata) ToMapClaims() jwt.MapClaims {
return mClaims
}
type TokenGenerator interface {
Generate(metadata Metadata) (string, error)
ExtractAccessTokenMetadata(token string) (*Metadata, error)
}
type tokenGenerator struct {
type TokenGenerator struct {
accessSecret string
}
func NewTokenGenerator(accessSecret string) TokenGenerator {
return &tokenGenerator{
func NewTokenGenerator(accessSecret string) *TokenGenerator {
return &TokenGenerator{
accessSecret: accessSecret,
}
}
func (g *tokenGenerator) Generate(metadata Metadata) (string, error) {
func (g *TokenGenerator) Generate(metadata Metadata) (string, error) {
atClaims := metadata.ToMapClaims()
if !metadata.StaySignedIn {
atClaims["exp"] = time.Now().Add(time.Hour * 24).Unix()
@ -54,7 +49,7 @@ func (g *tokenGenerator) Generate(metadata Metadata) (string, error) {
return accessToken, nil
}
func (g *tokenGenerator) ExtractAccessTokenMetadata(token string) (*Metadata, error) {
func (g *TokenGenerator) ExtractAccessTokenMetadata(token string) (*Metadata, error) {
return extractTokenMetadata(g.accessSecret, token)
}

View File

@ -3,10 +3,10 @@ package auth
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type Usecase interface {
SignIn(ctx context.Context, email, password string, staySignedIn bool) (*models.User, string, error)
ExtractAccessTokenMetadata(ctx context.Context, accessToken string) (*models.User, error)
SignIn(ctx context.Context, email, password string, staySignedIn bool) (*model.User, string, error)
ExtractAccessTokenMetadata(ctx context.Context, accessToken string) (*model.User, error)
}

View File

@ -3,34 +3,37 @@ package usecase
import (
"context"
"github.com/pkg/errors"
"github.com/zdam-egzamin-zawodowy/backend/internal/auth"
"github.com/zdam-egzamin-zawodowy/backend/internal/auth/jwt"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/user"
"github.com/zdam-egzamin-zawodowy/backend/pkg/util/errorutil"
)
type usecase struct {
userRepository user.Repository
tokenGenerator jwt.TokenGenerator
}
type Config struct {
UserRepository user.Repository
TokenGenerator jwt.TokenGenerator
TokenGenerator *jwt.TokenGenerator
}
func New(cfg *Config) (auth.Usecase, error) {
type Usecase struct {
userRepository user.Repository
tokenGenerator *jwt.TokenGenerator
}
var _ auth.Usecase = &Usecase{}
func New(cfg *Config) (*Usecase, error) {
if cfg == nil || cfg.UserRepository == nil {
return nil, errors.New("cfg.UserRepository is required")
}
return &usecase{
return &Usecase{
cfg.UserRepository,
cfg.TokenGenerator,
}, nil
}
func (ucase *usecase) SignIn(ctx context.Context, email, password string, staySignedIn bool) (*models.User, string, error) {
func (ucase *Usecase) SignIn(ctx context.Context, email, password string, staySignedIn bool) (*model.User, string, error) {
u, err := ucase.GetUserByCredentials(ctx, email, password)
if err != nil {
return nil, "", err
@ -50,7 +53,7 @@ func (ucase *usecase) SignIn(ctx context.Context, email, password string, staySi
return u, token, nil
}
func (ucase *usecase) ExtractAccessTokenMetadata(ctx context.Context, accessToken string) (*models.User, error) {
func (ucase *Usecase) ExtractAccessTokenMetadata(ctx context.Context, accessToken string) (*model.User, error) {
metadata, err := ucase.tokenGenerator.ExtractAccessTokenMetadata(accessToken)
if err != nil {
return nil, errorutil.Wrap(err, messageInvalidAccessToken)
@ -59,11 +62,11 @@ func (ucase *usecase) ExtractAccessTokenMetadata(ctx context.Context, accessToke
return ucase.GetUserByCredentials(ctx, metadata.Credentials.Email, metadata.Credentials.Password)
}
func (ucase *usecase) GetUserByCredentials(ctx context.Context, email, password string) (*models.User, error) {
func (ucase *Usecase) GetUserByCredentials(ctx context.Context, email, password string) (*model.User, error) {
users, _, err := ucase.userRepository.Fetch(ctx, &user.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.UserFilter{
Filter: &model.UserFilter{
Email: []string{email},
},
})

View File

@ -5,8 +5,9 @@ import (
"github.com/pkg/errors"
"github.com/gin-gonic/gin"
"github.com/zdam-egzamin-zawodowy/backend/internal/auth"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
const (
@ -32,16 +33,16 @@ func Authenticate(ucase auth.Usecase) gin.HandlerFunc {
}
}
func UserFromContext(ctx context.Context) (*models.User, error) {
func UserFromContext(ctx context.Context) (*model.User, error) {
user := ctx.Value(authenticateKey)
if user == nil {
err := errors.New("couldn't retrieve *models.User")
err := errors.New("couldn't retrieve *model.User")
return nil, err
}
u, ok := user.(*models.User)
u, ok := user.(*model.User)
if !ok {
err := errors.New("*models.User has wrong type")
err := errors.New("*model.User has wrong type")
return nil, err
}
return u, nil

View File

@ -2,10 +2,11 @@ package dataloader
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
"time"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/qualification"
)
@ -27,9 +28,9 @@ func New(cfg Config) *DataLoader {
return &DataLoader{
QualificationByID: NewQualificationLoader(QualificationLoaderConfig{
Wait: wait,
Fetch: func(ids []int) ([]*models.Qualification, []error) {
Fetch: func(ids []int) ([]*model.Qualification, []error) {
qualificationsNotInOrder, _, err := cfg.QualificationRepo.Fetch(context.Background(), &qualification.FetchConfig{
Filter: &models.QualificationFilter{
Filter: &model.QualificationFilter{
ID: ids,
},
Count: false,
@ -37,11 +38,11 @@ func New(cfg Config) *DataLoader {
if err != nil {
return nil, []error{err}
}
qualificationByID := make(map[int]*models.Qualification)
qualificationByID := make(map[int]*model.Qualification)
for _, qualification := range qualificationsNotInOrder {
qualificationByID[qualification.ID] = qualification
}
qualifications := make([]*models.Qualification, len(ids))
qualifications := make([]*model.Qualification, len(ids))
for i, id := range ids {
qualifications[i] = qualificationByID[id]
}
@ -50,13 +51,13 @@ func New(cfg Config) *DataLoader {
}),
QualificationsByProfessionID: NewQualificationSliceByProfessionIDLoader(QualificationSliceByProfessionIDLoaderConfig{
Wait: wait,
Fetch: func(ids []int) ([][]*models.Qualification, []error) {
Fetch: func(ids []int) ([][]*model.Qualification, []error) {
m, err := cfg.ProfessionRepo.GetAssociatedQualifications(context.Background(), ids...)
if err != nil {
return nil, []error{err}
}
qualifications := make([][]*models.Qualification, len(ids))
qualifications := make([][]*model.Qualification, len(ids))
for i, id := range ids {
qualifications[i] = m[id]

View File

@ -6,13 +6,13 @@ import (
"sync"
"time"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
// QualificationLoaderConfig captures the config to create a new QualificationLoader
type QualificationLoaderConfig struct {
// Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([]*models.Qualification, []error)
Fetch func(keys []int) ([]*model.Qualification, []error)
// Wait is how long wait before sending a batch
Wait time.Duration
@ -33,7 +33,7 @@ func NewQualificationLoader(config QualificationLoaderConfig) *QualificationLoad
// QualificationLoader batches and caches requests
type QualificationLoader struct {
// this method provides the data for the loader
fetch func(keys []int) ([]*models.Qualification, []error)
fetch func(keys []int) ([]*model.Qualification, []error)
// how long to done before sending a batch
wait time.Duration
@ -44,7 +44,7 @@ type QualificationLoader struct {
// INTERNAL
// lazily created cache
cache map[int]*models.Qualification
cache map[int]*model.Qualification
// the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners
@ -56,25 +56,25 @@ type QualificationLoader struct {
type qualificationLoaderBatch struct {
keys []int
data []*models.Qualification
data []*model.Qualification
error []error
closing bool
done chan struct{}
}
// Load a Qualification by key, batching and caching will be applied automatically
func (l *QualificationLoader) Load(key int) (*models.Qualification, error) {
func (l *QualificationLoader) Load(key int) (*model.Qualification, error) {
return l.LoadThunk(key)()
}
// LoadThunk returns a function that when called will block waiting for a Qualification.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *QualificationLoader) LoadThunk(key int) func() (*models.Qualification, error) {
func (l *QualificationLoader) LoadThunk(key int) func() (*model.Qualification, error) {
l.mu.Lock()
if it, ok := l.cache[key]; ok {
l.mu.Unlock()
return func() (*models.Qualification, error) {
return func() (*model.Qualification, error) {
return it, nil
}
}
@ -85,10 +85,10 @@ func (l *QualificationLoader) LoadThunk(key int) func() (*models.Qualification,
pos := batch.keyIndex(l, key)
l.mu.Unlock()
return func() (*models.Qualification, error) {
return func() (*model.Qualification, error) {
<-batch.done
var data *models.Qualification
var data *model.Qualification
if pos < len(batch.data) {
data = batch.data[pos]
}
@ -113,14 +113,14 @@ func (l *QualificationLoader) LoadThunk(key int) func() (*models.Qualification,
// LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured
func (l *QualificationLoader) LoadAll(keys []int) ([]*models.Qualification, []error) {
results := make([]func() (*models.Qualification, error), len(keys))
func (l *QualificationLoader) LoadAll(keys []int) ([]*model.Qualification, []error) {
results := make([]func() (*model.Qualification, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
qualifications := make([]*models.Qualification, len(keys))
qualifications := make([]*model.Qualification, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
qualifications[i], errors[i] = thunk()
@ -131,13 +131,13 @@ func (l *QualificationLoader) LoadAll(keys []int) ([]*models.Qualification, []er
// LoadAllThunk returns a function that when called will block waiting for a Qualifications.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *QualificationLoader) LoadAllThunk(keys []int) func() ([]*models.Qualification, []error) {
results := make([]func() (*models.Qualification, error), len(keys))
func (l *QualificationLoader) LoadAllThunk(keys []int) func() ([]*model.Qualification, []error) {
results := make([]func() (*model.Qualification, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
return func() ([]*models.Qualification, []error) {
qualifications := make([]*models.Qualification, len(keys))
return func() ([]*model.Qualification, []error) {
qualifications := make([]*model.Qualification, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
qualifications[i], errors[i] = thunk()
@ -149,7 +149,7 @@ func (l *QualificationLoader) LoadAllThunk(keys []int) func() ([]*models.Qualifi
// Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *QualificationLoader) Prime(key int, value *models.Qualification) bool {
func (l *QualificationLoader) Prime(key int, value *model.Qualification) bool {
l.mu.Lock()
var found bool
if _, found = l.cache[key]; !found {
@ -169,9 +169,9 @@ func (l *QualificationLoader) Clear(key int) {
l.mu.Unlock()
}
func (l *QualificationLoader) unsafeSet(key int, value *models.Qualification) {
func (l *QualificationLoader) unsafeSet(key int, value *model.Qualification) {
if l.cache == nil {
l.cache = map[int]*models.Qualification{}
l.cache = map[int]*model.Qualification{}
}
l.cache[key] = value
}

View File

@ -6,13 +6,13 @@ import (
"sync"
"time"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
// QualificationSliceByProfessionIDLoaderConfig captures the config to create a new QualificationSliceByProfessionIDLoader
type QualificationSliceByProfessionIDLoaderConfig struct {
// Fetch is a method that provides the data for the loader
Fetch func(keys []int) ([][]*models.Qualification, []error)
Fetch func(keys []int) ([][]*model.Qualification, []error)
// Wait is how long wait before sending a batch
Wait time.Duration
@ -33,7 +33,7 @@ func NewQualificationSliceByProfessionIDLoader(config QualificationSliceByProfes
// QualificationSliceByProfessionIDLoader batches and caches requests
type QualificationSliceByProfessionIDLoader struct {
// this method provides the data for the loader
fetch func(keys []int) ([][]*models.Qualification, []error)
fetch func(keys []int) ([][]*model.Qualification, []error)
// how long to done before sending a batch
wait time.Duration
@ -44,7 +44,7 @@ type QualificationSliceByProfessionIDLoader struct {
// INTERNAL
// lazily created cache
cache map[int][]*models.Qualification
cache map[int][]*model.Qualification
// the current batch. keys will continue to be collected until timeout is hit,
// then everything will be sent to the fetch method and out to the listeners
@ -56,25 +56,25 @@ type QualificationSliceByProfessionIDLoader struct {
type qualificationSliceByProfessionIDLoaderBatch struct {
keys []int
data [][]*models.Qualification
data [][]*model.Qualification
error []error
closing bool
done chan struct{}
}
// Load a Qualification by key, batching and caching will be applied automatically
func (l *QualificationSliceByProfessionIDLoader) Load(key int) ([]*models.Qualification, error) {
func (l *QualificationSliceByProfessionIDLoader) Load(key int) ([]*model.Qualification, error) {
return l.LoadThunk(key)()
}
// LoadThunk returns a function that when called will block waiting for a Qualification.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *QualificationSliceByProfessionIDLoader) LoadThunk(key int) func() ([]*models.Qualification, error) {
func (l *QualificationSliceByProfessionIDLoader) LoadThunk(key int) func() ([]*model.Qualification, error) {
l.mu.Lock()
if it, ok := l.cache[key]; ok {
l.mu.Unlock()
return func() ([]*models.Qualification, error) {
return func() ([]*model.Qualification, error) {
return it, nil
}
}
@ -85,10 +85,10 @@ func (l *QualificationSliceByProfessionIDLoader) LoadThunk(key int) func() ([]*m
pos := batch.keyIndex(l, key)
l.mu.Unlock()
return func() ([]*models.Qualification, error) {
return func() ([]*model.Qualification, error) {
<-batch.done
var data []*models.Qualification
var data []*model.Qualification
if pos < len(batch.data) {
data = batch.data[pos]
}
@ -113,14 +113,14 @@ func (l *QualificationSliceByProfessionIDLoader) LoadThunk(key int) func() ([]*m
// LoadAll fetches many keys at once. It will be broken into appropriate sized
// sub batches depending on how the loader is configured
func (l *QualificationSliceByProfessionIDLoader) LoadAll(keys []int) ([][]*models.Qualification, []error) {
results := make([]func() ([]*models.Qualification, error), len(keys))
func (l *QualificationSliceByProfessionIDLoader) LoadAll(keys []int) ([][]*model.Qualification, []error) {
results := make([]func() ([]*model.Qualification, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
qualifications := make([][]*models.Qualification, len(keys))
qualifications := make([][]*model.Qualification, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
qualifications[i], errors[i] = thunk()
@ -131,13 +131,13 @@ func (l *QualificationSliceByProfessionIDLoader) LoadAll(keys []int) ([][]*model
// LoadAllThunk returns a function that when called will block waiting for a Qualifications.
// This method should be used if you want one goroutine to make requests to many
// different data loaders without blocking until the thunk is called.
func (l *QualificationSliceByProfessionIDLoader) LoadAllThunk(keys []int) func() ([][]*models.Qualification, []error) {
results := make([]func() ([]*models.Qualification, error), len(keys))
func (l *QualificationSliceByProfessionIDLoader) LoadAllThunk(keys []int) func() ([][]*model.Qualification, []error) {
results := make([]func() ([]*model.Qualification, error), len(keys))
for i, key := range keys {
results[i] = l.LoadThunk(key)
}
return func() ([][]*models.Qualification, []error) {
qualifications := make([][]*models.Qualification, len(keys))
return func() ([][]*model.Qualification, []error) {
qualifications := make([][]*model.Qualification, len(keys))
errors := make([]error, len(keys))
for i, thunk := range results {
qualifications[i], errors[i] = thunk()
@ -149,13 +149,13 @@ func (l *QualificationSliceByProfessionIDLoader) LoadAllThunk(keys []int) func()
// Prime the cache with the provided key and value. If the key already exists, no change is made
// and false is returned.
// (To forcefully prime the cache, clear the key first with loader.clear(key).prime(key, value).)
func (l *QualificationSliceByProfessionIDLoader) Prime(key int, value []*models.Qualification) bool {
func (l *QualificationSliceByProfessionIDLoader) Prime(key int, value []*model.Qualification) bool {
l.mu.Lock()
var found bool
if _, found = l.cache[key]; !found {
// make a copy when writing to the cache, its easy to pass a pointer in from a loop var
// and end up with the whole cache pointing to the same value.
cpy := make([]*models.Qualification, len(value))
cpy := make([]*model.Qualification, len(value))
copy(cpy, value)
l.unsafeSet(key, cpy)
}
@ -170,9 +170,9 @@ func (l *QualificationSliceByProfessionIDLoader) Clear(key int) {
l.mu.Unlock()
}
func (l *QualificationSliceByProfessionIDLoader) unsafeSet(key int, value []*models.Qualification) {
func (l *QualificationSliceByProfessionIDLoader) unsafeSet(key int, value []*model.Qualification) {
if l.cache == nil {
l.cache = map[int][]*models.Qualification{}
l.cache = map[int][]*model.Qualification{}
}
l.cache[key] = value
}

View File

@ -5,8 +5,9 @@ import (
"github.com/pkg/errors"
"github.com/99designs/gqlgen/graphql"
"github.com/zdam-egzamin-zawodowy/backend/internal/gin/middleware"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/pkg/util/errorutil"
)
@ -23,7 +24,7 @@ func (d *Directive) Authenticated(ctx context.Context, _ interface{}, next graph
return next(ctx)
}
func (d *Directive) HasRole(ctx context.Context, _ interface{}, next graphql.Resolver, role models.Role) (interface{}, error) {
func (d *Directive) HasRole(ctx context.Context, _ interface{}, next graphql.Resolver, role model.Role) (interface{}, error) {
user, err := middleware.UserFromContext(ctx)
if err != nil {
return nil, errorutil.Wrap(err, messageMustBeSignedIn)

File diff suppressed because it is too large Load Diff

View File

@ -3,30 +3,30 @@
package generated
import (
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type ProfessionList struct {
Total int `json:"total"`
Items []*models.Profession `json:"items"`
Total int `json:"total"`
Items []*model.Profession `json:"items"`
}
type QualificationList struct {
Total int `json:"total"`
Items []*models.Qualification `json:"items"`
Total int `json:"total"`
Items []*model.Qualification `json:"items"`
}
type QuestionList struct {
Total int `json:"total"`
Items []*models.Question `json:"items"`
Total int `json:"total"`
Items []*model.Question `json:"items"`
}
type UserList struct {
Total int `json:"total"`
Items []*models.User `json:"items"`
Total int `json:"total"`
Items []*model.User `json:"items"`
}
type UserWithToken struct {
Token string `json:"token"`
User *models.User `json:"user"`
Token string `json:"token"`
User *model.User `json:"user"`
}

View File

@ -19,52 +19,52 @@ models:
- github.com/99designs/gqlgen/graphql.Int32
Role:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Role
- github.com/zdam-egzamin-zawodowy/backend/internal/model.Role
User:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.User
- github.com/zdam-egzamin-zawodowy/backend/internal/model.User
UserFilter:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserFilter
- github.com/zdam-egzamin-zawodowy/backend/internal/model.UserFilter
UserFilterOr:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserFilterOr
- github.com/zdam-egzamin-zawodowy/backend/internal/model.UserFilterOr
UserInput:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserInput
- github.com/zdam-egzamin-zawodowy/backend/internal/model.UserInput
UpdateManyUsersInput:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.UserInput
- github.com/zdam-egzamin-zawodowy/backend/internal/model.UserInput
Profession:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Profession
- github.com/zdam-egzamin-zawodowy/backend/internal/model.Profession
ProfessionFilter:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.ProfessionFilter
- github.com/zdam-egzamin-zawodowy/backend/internal/model.ProfessionFilter
ProfessionInput:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.ProfessionInput
- github.com/zdam-egzamin-zawodowy/backend/internal/model.ProfessionInput
Qualification:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Qualification
- github.com/zdam-egzamin-zawodowy/backend/internal/model.Qualification
QualificationFilter:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QualificationFilter
- github.com/zdam-egzamin-zawodowy/backend/internal/model.QualificationFilter
QualificationFilterOr:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QualificationFilterOr
- github.com/zdam-egzamin-zawodowy/backend/internal/model.QualificationFilterOr
QualificationInput:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QualificationInput
- github.com/zdam-egzamin-zawodowy/backend/internal/model.QualificationInput
Answer:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Answer
- github.com/zdam-egzamin-zawodowy/backend/internal/model.Answer
Question:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.Question
- github.com/zdam-egzamin-zawodowy/backend/internal/model.Question
QuestionFilter:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QuestionFilter
- github.com/zdam-egzamin-zawodowy/backend/internal/model.QuestionFilter
QuestionInput:
model:
- github.com/zdam-egzamin-zawodowy/backend/internal/models.QuestionInput
- github.com/zdam-egzamin-zawodowy/backend/internal/model.QuestionInput

View File

@ -3,8 +3,9 @@ package querycomplexity
import (
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/Kichiyaki/goutil/safeptr"
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
"github.com/zdam-egzamin-zawodowy/backend/internal/qualification"
"github.com/zdam-egzamin-zawodowy/backend/internal/question"
@ -33,7 +34,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.ProfessionList.Total = getCountComplexity
complexityRoot.Query.Professions = func(
childComplexity int,
filter *models.ProfessionFilter,
filter *model.ProfessionFilter,
limit *int,
offset *int,
sort []string,
@ -49,7 +50,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.QualificationList.Total = getCountComplexity
complexityRoot.Query.Qualifications = func(
childComplexity int,
filter *models.QualificationFilter,
filter *model.QualificationFilter,
limit *int,
offset *int,
sort []string,
@ -65,7 +66,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.QuestionList.Total = getCountComplexity
complexityRoot.Query.Questions = func(
childComplexity int,
filter *models.QuestionFilter,
filter *model.QuestionFilter,
limit *int,
offset *int,
sort []string,
@ -89,7 +90,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.UserList.Total = getCountComplexity
complexityRoot.Query.Users = func(
childComplexity int,
filter *models.UserFilter,
filter *model.UserFilter,
limit *int,
offset *int,
sort []string,
@ -102,22 +103,22 @@ func GetComplexityRoot() generated.ComplexityRoot {
)
}
complexityRoot.Mutation.CreateProfession = func(childComplexity int, input models.ProfessionInput) int {
complexityRoot.Mutation.CreateProfession = func(childComplexity int, input model.ProfessionInput) int {
return (complexityLimit / 5) + childComplexity
}
complexityRoot.Mutation.CreateQualification = func(
childComplexity int,
input models.QualificationInput,
input model.QualificationInput,
) int {
return (complexityLimit / 5) + childComplexity
}
complexityRoot.Mutation.CreateQuestion = func(childComplexity int, input models.QuestionInput) int {
complexityRoot.Mutation.CreateQuestion = func(childComplexity int, input model.QuestionInput) int {
return (complexityLimit / 4) + childComplexity
}
complexityRoot.Mutation.CreateUser = func(childComplexity int, input models.UserInput) int {
complexityRoot.Mutation.CreateUser = func(childComplexity int, input model.UserInput) int {
return (complexityLimit / 5) + childComplexity
}
@ -133,7 +134,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Mutation.UpdateManyUsers = func(
childComplexity int,
ids []int,
input models.UserInput,
input model.UserInput,
) int {
return (complexityLimit / 5) + childComplexity
}
@ -141,7 +142,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Mutation.UpdateProfession = func(
childComplexity int,
id int,
input models.ProfessionInput,
input model.ProfessionInput,
) int {
return (complexityLimit / 5) + childComplexity
}
@ -149,7 +150,7 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Mutation.UpdateQualification = func(
childComplexity int,
id int,
input models.QualificationInput,
input model.QualificationInput,
) int {
return (complexityLimit / 5) + childComplexity
}
@ -157,12 +158,12 @@ func GetComplexityRoot() generated.ComplexityRoot {
complexityRoot.Mutation.UpdateQuestion = func(
childComplexity int,
id int,
input models.QuestionInput,
input model.QuestionInput,
) int {
return (complexityLimit / 4) + childComplexity
}
complexityRoot.Mutation.UpdateUser = func(childComplexity int, id int, input models.UserInput) int {
complexityRoot.Mutation.UpdateUser = func(childComplexity int, id int, input model.UserInput) int {
return (complexityLimit / 5) + childComplexity
}

View File

@ -6,30 +6,31 @@ package resolvers
import (
"context"
"github.com/Kichiyaki/goutil/safeptr"
"github.com/zdam-egzamin-zawodowy/backend/internal/gin/middleware"
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
)
func (r *mutationResolver) CreateProfession(ctx context.Context, input models.ProfessionInput) (*models.Profession, error) {
func (r *mutationResolver) CreateProfession(ctx context.Context, input model.ProfessionInput) (*model.Profession, error) {
return r.ProfessionUsecase.Store(ctx, &input)
}
func (r *mutationResolver) UpdateProfession(ctx context.Context, id int, input models.ProfessionInput) (*models.Profession, error) {
func (r *mutationResolver) UpdateProfession(ctx context.Context, id int, input model.ProfessionInput) (*model.Profession, error) {
return r.ProfessionUsecase.UpdateOneByID(ctx, id, &input)
}
func (r *mutationResolver) DeleteProfessions(ctx context.Context, ids []int) ([]*models.Profession, error) {
return r.ProfessionUsecase.Delete(ctx, &models.ProfessionFilter{
func (r *mutationResolver) DeleteProfessions(ctx context.Context, ids []int) ([]*model.Profession, error) {
return r.ProfessionUsecase.Delete(ctx, &model.ProfessionFilter{
ID: ids,
})
}
func (r *queryResolver) Professions(
ctx context.Context,
filter *models.ProfessionFilter,
filter *model.ProfessionFilter,
limit *int,
offset *int,
sort []string,
@ -49,7 +50,7 @@ func (r *queryResolver) Professions(
return list, err
}
func (r *queryResolver) Profession(ctx context.Context, id *int, slug *string) (*models.Profession, error) {
func (r *queryResolver) Profession(ctx context.Context, id *int, slug *string) (*model.Profession, error) {
if id != nil {
return r.ProfessionUsecase.GetByID(ctx, *id)
} else if slug != nil {
@ -61,12 +62,12 @@ func (r *queryResolver) Profession(ctx context.Context, id *int, slug *string) (
func (r *professionResolver) Qualifications(
ctx context.Context,
obj *models.Profession,
) ([]*models.Qualification, error) {
obj *model.Profession,
) ([]*model.Qualification, error) {
if obj != nil {
if dataloader, err := middleware.DataLoaderFromContext(ctx); err == nil && dataloader != nil {
return dataloader.QualificationsByProfessionID.Load(obj.ID)
}
}
return []*models.Qualification{}, nil
return []*model.Qualification{}, nil
}

View File

@ -8,27 +8,27 @@ import (
"github.com/Kichiyaki/goutil/safeptr"
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/qualification"
)
func (r *mutationResolver) CreateQualification(ctx context.Context, input models.QualificationInput) (*models.Qualification, error) {
func (r *mutationResolver) CreateQualification(ctx context.Context, input model.QualificationInput) (*model.Qualification, error) {
return r.QualificationUsecase.Store(ctx, &input)
}
func (r *mutationResolver) UpdateQualification(ctx context.Context, id int, input models.QualificationInput) (*models.Qualification, error) {
func (r *mutationResolver) UpdateQualification(ctx context.Context, id int, input model.QualificationInput) (*model.Qualification, error) {
return r.QualificationUsecase.UpdateOneByID(ctx, id, &input)
}
func (r *mutationResolver) DeleteQualifications(ctx context.Context, ids []int) ([]*models.Qualification, error) {
return r.QualificationUsecase.Delete(ctx, &models.QualificationFilter{
func (r *mutationResolver) DeleteQualifications(ctx context.Context, ids []int) ([]*model.Qualification, error) {
return r.QualificationUsecase.Delete(ctx, &model.QualificationFilter{
ID: ids,
})
}
func (r *queryResolver) Qualifications(
ctx context.Context,
filter *models.QualificationFilter,
filter *model.QualificationFilter,
limit *int,
offset *int,
sort []string,
@ -70,7 +70,7 @@ func (r *queryResolver) SimilarQualifications(
return list, err
}
func (r *queryResolver) Qualification(ctx context.Context, id *int, slug *string) (*models.Qualification, error) {
func (r *queryResolver) Qualification(ctx context.Context, id *int, slug *string) (*model.Qualification, error) {
if id != nil {
return r.QualificationUsecase.GetByID(ctx, *id)
} else if slug != nil {

View File

@ -9,25 +9,25 @@ import (
"github.com/zdam-egzamin-zawodowy/backend/internal/gin/middleware"
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/question"
)
func (r *mutationResolver) CreateQuestion(ctx context.Context, input models.QuestionInput) (*models.Question, error) {
func (r *mutationResolver) CreateQuestion(ctx context.Context, input model.QuestionInput) (*model.Question, error) {
return r.QuestionUsecase.Store(ctx, &input)
}
func (r *mutationResolver) UpdateQuestion(ctx context.Context, id int, input models.QuestionInput) (*models.Question, error) {
func (r *mutationResolver) UpdateQuestion(ctx context.Context, id int, input model.QuestionInput) (*model.Question, error) {
return r.QuestionUsecase.UpdateOneByID(ctx, id, &input)
}
func (r *mutationResolver) DeleteQuestions(ctx context.Context, ids []int) ([]*models.Question, error) {
return r.QuestionUsecase.Delete(ctx, &models.QuestionFilter{
func (r *mutationResolver) DeleteQuestions(ctx context.Context, ids []int) ([]*model.Question, error) {
return r.QuestionUsecase.Delete(ctx, &model.QuestionFilter{
ID: ids,
})
}
func (r *queryResolver) GenerateTest(ctx context.Context, qualificationIDs []int, limit *int) ([]*models.Question, error) {
func (r *queryResolver) GenerateTest(ctx context.Context, qualificationIDs []int, limit *int) ([]*model.Question, error) {
return r.QuestionUsecase.GenerateTest(ctx, &question.GenerateTestConfig{
Qualifications: qualificationIDs,
Limit: safeptr.SafeIntPointer(limit, question.TestMaxLimit),
@ -36,7 +36,7 @@ func (r *queryResolver) GenerateTest(ctx context.Context, qualificationIDs []int
func (r *queryResolver) Questions(
ctx context.Context,
filter *models.QuestionFilter,
filter *model.QuestionFilter,
limit *int,
offset *int,
sort []string,
@ -56,7 +56,7 @@ func (r *queryResolver) Questions(
return list, err
}
func (r *questionResolver) Qualification(ctx context.Context, obj *models.Question) (*models.Qualification, error) {
func (r *questionResolver) Qualification(ctx context.Context, obj *model.Question) (*model.Qualification, error) {
if obj != nil && obj.Qualification != nil {
return obj.Qualification, nil
}

View File

@ -9,30 +9,30 @@ import (
"github.com/zdam-egzamin-zawodowy/backend/internal/gin/middleware"
"github.com/zdam-egzamin-zawodowy/backend/internal/graphql/generated"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/user"
)
func (r *mutationResolver) CreateUser(ctx context.Context, input models.UserInput) (*models.User, error) {
func (r *mutationResolver) CreateUser(ctx context.Context, input model.UserInput) (*model.User, error) {
return r.UserUsecase.Store(ctx, &input)
}
func (r *mutationResolver) UpdateUser(ctx context.Context, id int, input models.UserInput) (*models.User, error) {
func (r *mutationResolver) UpdateUser(ctx context.Context, id int, input model.UserInput) (*model.User, error) {
return r.UserUsecase.UpdateOneByID(ctx, id, &input)
}
func (r *mutationResolver) UpdateManyUsers(ctx context.Context, ids []int, input models.UserInput) ([]*models.User, error) {
func (r *mutationResolver) UpdateManyUsers(ctx context.Context, ids []int, input model.UserInput) ([]*model.User, error) {
return r.UserUsecase.UpdateMany(
ctx,
&models.UserFilter{
&model.UserFilter{
ID: ids,
},
&input,
)
}
func (r *mutationResolver) DeleteUsers(ctx context.Context, ids []int) ([]*models.User, error) {
return r.UserUsecase.Delete(ctx, &models.UserFilter{
func (r *mutationResolver) DeleteUsers(ctx context.Context, ids []int) ([]*model.User, error) {
return r.UserUsecase.Delete(ctx, &model.UserFilter{
ID: ids,
})
}
@ -59,7 +59,7 @@ func (r *mutationResolver) SignIn(
func (r *queryResolver) Users(
ctx context.Context,
filter *models.UserFilter,
filter *model.UserFilter,
limit *int,
offset *int,
sort []string,
@ -79,11 +79,11 @@ func (r *queryResolver) Users(
return userList, err
}
func (r *queryResolver) User(ctx context.Context, id int) (*models.User, error) {
func (r *queryResolver) User(ctx context.Context, id int) (*model.User, error) {
return r.UserUsecase.GetByID(ctx, id)
}
func (r *queryResolver) Me(ctx context.Context) (*models.User, error) {
func (r *queryResolver) Me(ctx context.Context) (*model.User, error) {
u, _ := middleware.UserFromContext(ctx)
return u, nil
}

View File

@ -1,4 +1,4 @@
package models
package model
import (
"fmt"

View File

@ -1,4 +1,4 @@
package models
package model
import (
"reflect"

View File

@ -1,4 +1,4 @@
package models
package model
import (
"context"

View File

@ -1,4 +1,4 @@
package models
package model
import (
"context"

View File

@ -1,4 +1,4 @@
package models
package model
import (
"context"

View File

@ -1,4 +1,4 @@
package models
package model
import (
"fmt"

View File

@ -1,4 +1,4 @@
package models
package model
import (
"context"

View File

@ -10,7 +10,8 @@ import (
"github.com/go-pg/pg/v10/orm"
"github.com/pkg/errors"
"github.com/sethvargo/go-password/password"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
var log = logrus.WithField("package", "internal/postgres")
@ -20,7 +21,7 @@ type Config struct {
}
func init() {
orm.RegisterTable((*models.QualificationToProfession)(nil))
orm.RegisterTable((*model.QualificationToProfession)(nil))
}
func Connect(cfg *Config) (*pg.DB, error) {
@ -55,11 +56,11 @@ func prepareOptions() *pg.Options {
func createSchema(db *pg.DB) error {
return db.RunInTransaction(context.Background(), func(tx *pg.Tx) error {
modelsToCreate := []interface{}{
(*models.User)(nil),
(*models.Profession)(nil),
(*models.Qualification)(nil),
(*models.QualificationToProfession)(nil),
(*models.Question)(nil),
(*model.User)(nil),
(*model.Profession)(nil),
(*model.Qualification)(nil),
(*model.QualificationToProfession)(nil),
(*model.Question)(nil),
}
for _, model := range modelsToCreate {
@ -72,7 +73,7 @@ func createSchema(db *pg.DB) error {
}
}
total, err := tx.Model(modelsToCreate[0]).Where("role = ?", models.RoleAdmin).Count()
total, err := tx.Model(modelsToCreate[0]).Where("role = ?", model.RoleAdmin).Count()
if err != nil {
return errors.Wrap(err, "couldn't count admins")
}
@ -84,10 +85,10 @@ func createSchema(db *pg.DB) error {
}
email := "admin@admin.com"
_, err = tx.
Model(&models.User{
Model(&model.User{
DisplayName: "admin",
Email: email,
Role: models.RoleAdmin,
Role: model.RoleAdmin,
Activated: &activated,
Password: pswd,
}).

View File

@ -3,11 +3,11 @@ package profession
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type FetchConfig struct {
Filter *models.ProfessionFilter
Filter *model.ProfessionFilter
Offset int
Limit int
Sort []string
@ -15,9 +15,9 @@ type FetchConfig struct {
}
type Repository interface {
Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error)
UpdateMany(ctx context.Context, f *models.ProfessionFilter, input *models.ProfessionInput) ([]*models.Profession, error)
Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Profession, int, error)
GetAssociatedQualifications(ctx context.Context, ids ...int) (map[int][]*models.Qualification, error)
Store(ctx context.Context, input *model.ProfessionInput) (*model.Profession, error)
UpdateMany(ctx context.Context, f *model.ProfessionFilter, input *model.ProfessionInput) ([]*model.Profession, error)
Delete(ctx context.Context, f *model.ProfessionFilter) ([]*model.Profession, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.Profession, int, error)
GetAssociatedQualifications(ctx context.Context, ids ...int) (map[int][]*model.Qualification, error)
}

View File

@ -9,28 +9,31 @@ import (
"github.com/zdam-egzamin-zawodowy/backend/pkg/util/errorutil"
"github.com/go-pg/pg/v10"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
)
type pgRepository struct {
*pg.DB
}
type PGRepositoryConfig struct {
DB *pg.DB
}
func NewPGRepository(cfg *PGRepositoryConfig) (profession.Repository, error) {
type PGRepository struct {
*pg.DB
}
var _ profession.Repository = &PGRepository{}
func NewPGRepository(cfg *PGRepositoryConfig) (*PGRepository, error) {
if cfg == nil || cfg.DB == nil {
return nil, errors.New("cfg.DB is required")
}
return &pgRepository{
return &PGRepository{
cfg.DB,
}, nil
}
func (repo *pgRepository) Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error) {
func (repo *PGRepository) Store(ctx context.Context, input *model.ProfessionInput) (*model.Profession, error) {
item := input.ToProfession()
if _, err := repo.
Model(item).
@ -42,9 +45,9 @@ func (repo *pgRepository) Store(ctx context.Context, input *models.ProfessionInp
return item, nil
}
func (repo *pgRepository) UpdateMany(ctx context.Context, f *models.ProfessionFilter, input *models.ProfessionInput) ([]*models.Profession, error) {
func (repo *PGRepository) UpdateMany(ctx context.Context, f *model.ProfessionFilter, input *model.ProfessionInput) ([]*model.Profession, error) {
if _, err := repo.
Model(&models.Profession{}).
Model(&model.Profession{}).
Context(ctx).
Apply(input.ApplyUpdate).
Apply(f.Where).
@ -61,8 +64,8 @@ func (repo *pgRepository) UpdateMany(ctx context.Context, f *models.ProfessionFi
return items, nil
}
func (repo *pgRepository) Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error) {
items := make([]*models.Profession, 0)
func (repo *PGRepository) Delete(ctx context.Context, f *model.ProfessionFilter) ([]*model.Profession, error) {
items := make([]*model.Profession, 0)
if _, err := repo.
Model(&items).
Context(ctx).
@ -74,9 +77,9 @@ func (repo *pgRepository) Delete(ctx context.Context, f *models.ProfessionFilter
return items, nil
}
func (repo *pgRepository) Fetch(ctx context.Context, cfg *profession.FetchConfig) ([]*models.Profession, int, error) {
func (repo *PGRepository) Fetch(ctx context.Context, cfg *profession.FetchConfig) ([]*model.Profession, int, error) {
var err error
items := make([]*models.Profession, 0)
items := make([]*model.Profession, 0)
total := 0
query := repo.
Model(&items).
@ -99,15 +102,15 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg *profession.FetchConfig
return items, total, nil
}
func (repo *pgRepository) GetAssociatedQualifications(
func (repo *PGRepository) GetAssociatedQualifications(
ctx context.Context,
ids ...int,
) (map[int][]*models.Qualification, error) {
m := make(map[int][]*models.Qualification)
) (map[int][]*model.Qualification, error) {
m := make(map[int][]*model.Qualification)
for _, id := range ids {
m[id] = make([]*models.Qualification, 0)
m[id] = make([]*model.Qualification, 0)
}
var qualificationToProfession []*models.QualificationToProfession
var qualificationToProfession []*model.QualificationToProfession
if err := repo.
Model(&qualificationToProfession).
Context(ctx).

View File

@ -3,14 +3,14 @@ package profession
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type Usecase interface {
Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error)
UpdateOneByID(ctx context.Context, id int, input *models.ProfessionInput) (*models.Profession, error)
Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Profession, int, error)
GetByID(ctx context.Context, id int) (*models.Profession, error)
GetBySlug(ctx context.Context, slug string) (*models.Profession, error)
Store(ctx context.Context, input *model.ProfessionInput) (*model.Profession, error)
UpdateOneByID(ctx context.Context, id int, input *model.ProfessionInput) (*model.Profession, error)
Delete(ctx context.Context, f *model.ProfessionFilter) ([]*model.Profession, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.Profession, int, error)
GetByID(ctx context.Context, id int) (*model.Profession, error)
GetBySlug(ctx context.Context, slug string) (*model.Profession, error)
}

View File

@ -4,35 +4,37 @@ import (
"context"
"github.com/pkg/errors"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
)
type usecase struct {
professionRepository profession.Repository
}
type Config struct {
ProfessionRepository profession.Repository
}
func New(cfg *Config) (profession.Usecase, error) {
type Usecase struct {
professionRepository profession.Repository
}
var _ profession.Usecase = &Usecase{}
func New(cfg *Config) (*Usecase, error) {
if cfg == nil || cfg.ProfessionRepository == nil {
return nil, errors.New("cfg.ProfessionRepository is required")
}
return &usecase{
return &Usecase{
cfg.ProfessionRepository,
}, nil
}
func (ucase *usecase) Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error) {
func (ucase *Usecase) Store(ctx context.Context, input *model.ProfessionInput) (*model.Profession, error) {
if err := validateInput(input.Sanitize(), validateOptions{false}); err != nil {
return nil, err
}
return ucase.professionRepository.Store(ctx, input)
}
func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.ProfessionInput) (*models.Profession, error) {
func (ucase *Usecase) UpdateOneByID(ctx context.Context, id int, input *model.ProfessionInput) (*model.Profession, error) {
if id <= 0 {
return nil, errors.New(messageInvalidID)
}
@ -40,7 +42,7 @@ func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.P
return nil, err
}
items, err := ucase.professionRepository.UpdateMany(ctx,
&models.ProfessionFilter{
&model.ProfessionFilter{
ID: []int{id},
},
input)
@ -53,11 +55,11 @@ func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.P
return items[0], nil
}
func (ucase *usecase) Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error) {
func (ucase *Usecase) Delete(ctx context.Context, f *model.ProfessionFilter) ([]*model.Profession, error) {
return ucase.professionRepository.Delete(ctx, f)
}
func (ucase *usecase) Fetch(ctx context.Context, cfg *profession.FetchConfig) ([]*models.Profession, int, error) {
func (ucase *Usecase) Fetch(ctx context.Context, cfg *profession.FetchConfig) ([]*model.Profession, int, error) {
if cfg == nil {
cfg = &profession.FetchConfig{
Limit: profession.FetchDefaultLimit,
@ -71,11 +73,11 @@ func (ucase *usecase) Fetch(ctx context.Context, cfg *profession.FetchConfig) ([
return ucase.professionRepository.Fetch(ctx, cfg)
}
func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.Profession, error) {
func (ucase *Usecase) GetByID(ctx context.Context, id int) (*model.Profession, error) {
items, _, err := ucase.Fetch(ctx, &profession.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.ProfessionFilter{
Filter: &model.ProfessionFilter{
ID: []int{id},
},
})
@ -88,11 +90,11 @@ func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.Profession,
return items[0], nil
}
func (ucase *usecase) GetBySlug(ctx context.Context, slug string) (*models.Profession, error) {
func (ucase *Usecase) GetBySlug(ctx context.Context, slug string) (*model.Profession, error) {
items, _, err := ucase.Fetch(ctx, &profession.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.ProfessionFilter{
Filter: &model.ProfessionFilter{
Slug: []string{slug},
},
})
@ -109,7 +111,7 @@ type validateOptions struct {
allowNilValues bool
}
func validateInput(input *models.ProfessionInput, opts validateOptions) error {
func validateInput(input *model.ProfessionInput, opts validateOptions) error {
if input.IsEmpty() {
return errors.New(messageEmptyPayload)
}

View File

@ -3,11 +3,11 @@ package qualification
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type FetchConfig struct {
Filter *models.QualificationFilter
Filter *model.QualificationFilter
Offset int
Limit int
Sort []string
@ -23,9 +23,9 @@ type GetSimilarConfig struct {
}
type Repository interface {
Store(ctx context.Context, input *models.QualificationInput) (*models.Qualification, error)
UpdateMany(ctx context.Context, f *models.QualificationFilter, input *models.QualificationInput) ([]*models.Qualification, error)
Delete(ctx context.Context, f *models.QualificationFilter) ([]*models.Qualification, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Qualification, int, error)
GetSimilar(ctx context.Context, cfg *GetSimilarConfig) ([]*models.Qualification, int, error)
Store(ctx context.Context, input *model.QualificationInput) (*model.Qualification, error)
UpdateMany(ctx context.Context, f *model.QualificationFilter, input *model.QualificationInput) ([]*model.Qualification, error)
Delete(ctx context.Context, f *model.QualificationFilter) ([]*model.Qualification, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.Qualification, int, error)
GetSimilar(ctx context.Context, cfg *GetSimilarConfig) ([]*model.Qualification, int, error)
}

View File

@ -9,28 +9,31 @@ import (
"github.com/zdam-egzamin-zawodowy/backend/pkg/util/errorutil"
"github.com/go-pg/pg/v10"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/qualification"
)
type pgRepository struct {
*pg.DB
}
type PGRepositoryConfig struct {
DB *pg.DB
}
func NewPGRepository(cfg *PGRepositoryConfig) (qualification.Repository, error) {
type PGRepository struct {
*pg.DB
}
var _ qualification.Repository = &PGRepository{}
func NewPGRepository(cfg *PGRepositoryConfig) (*PGRepository, error) {
if cfg == nil || cfg.DB == nil {
return nil, errors.New("cfg.DB is required")
}
return &pgRepository{
return &PGRepository{
cfg.DB,
}, nil
}
func (repo *pgRepository) Store(ctx context.Context, input *models.QualificationInput) (*models.Qualification, error) {
func (repo *PGRepository) Store(ctx context.Context, input *model.QualificationInput) (*model.Qualification, error) {
item := input.ToQualification()
err := repo.RunInTransaction(ctx, func(tx *pg.Tx) error {
if _, err := tx.
@ -52,16 +55,16 @@ func (repo *pgRepository) Store(ctx context.Context, input *models.Qualification
return item, err
}
func (repo *pgRepository) UpdateMany(
func (repo *PGRepository) UpdateMany(
ctx context.Context,
f *models.QualificationFilter,
input *models.QualificationInput,
) ([]*models.Qualification, error) {
items := make([]*models.Qualification, 0)
f *model.QualificationFilter,
input *model.QualificationInput,
) ([]*model.Qualification, error) {
items := make([]*model.Qualification, 0)
err := repo.RunInTransaction(ctx, func(tx *pg.Tx) error {
if input.HasBasicDataToUpdate() {
if _, err := tx.
Model(&models.Qualification{}).
Model(&model.Qualification{}).
Context(ctx).
Apply(input.ApplyUpdate).
Apply(f.Where).
@ -86,7 +89,7 @@ func (repo *pgRepository) UpdateMany(
if len(qualificationIDs) > 0 {
if len(input.DissociateProfession) > 0 {
_, err := tx.
Model(&models.QualificationToProfession{}).
Model(&model.QualificationToProfession{}).
Where(gopgutil.BuildConditionArray("profession_id"), pg.Array(input.DissociateProfession)).
Where(gopgutil.BuildConditionArray("qualification_id"), pg.Array(qualificationIDs)).
Delete()
@ -107,8 +110,8 @@ func (repo *pgRepository) UpdateMany(
return items, err
}
func (repo *pgRepository) Delete(ctx context.Context, f *models.QualificationFilter) ([]*models.Qualification, error) {
items := make([]*models.Qualification, 0)
func (repo *PGRepository) Delete(ctx context.Context, f *model.QualificationFilter) ([]*model.Qualification, error) {
items := make([]*model.Qualification, 0)
if _, err := repo.
Model(&items).
Context(ctx).
@ -120,9 +123,9 @@ func (repo *pgRepository) Delete(ctx context.Context, f *models.QualificationFil
return items, nil
}
func (repo *pgRepository) Fetch(ctx context.Context, cfg *qualification.FetchConfig) ([]*models.Qualification, int, error) {
func (repo *PGRepository) Fetch(ctx context.Context, cfg *qualification.FetchConfig) ([]*model.Qualification, int, error) {
var err error
items := make([]*models.Qualification, 0)
items := make([]*model.Qualification, 0)
total := 0
query := repo.
Model(&items).
@ -145,16 +148,16 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg *qualification.FetchCon
return items, total, nil
}
func (repo *pgRepository) GetSimilar(ctx context.Context, cfg *qualification.GetSimilarConfig) ([]*models.Qualification, int, error) {
func (repo *PGRepository) GetSimilar(ctx context.Context, cfg *qualification.GetSimilarConfig) ([]*model.Qualification, int, error) {
var err error
subquery := repo.
Model(&models.QualificationToProfession{}).
Model(&model.QualificationToProfession{}).
Context(ctx).
Where(gopgutil.BuildConditionEquals("qualification_id"), cfg.QualificationID).
Column("profession_id")
var qualificationIDs []int
err = repo.
Model(&models.QualificationToProfession{}).
Model(&model.QualificationToProfession{}).
Context(ctx).
Column("qualification_id").
With("prof", subquery).
@ -166,25 +169,25 @@ func (repo *pgRepository) GetSimilar(ctx context.Context, cfg *qualification.Get
}
if len(qualificationIDs) == 0 {
return []*models.Qualification{}, 0, nil
return []*model.Qualification{}, 0, nil
}
return repo.Fetch(ctx, &qualification.FetchConfig{
Sort: cfg.Sort,
Limit: cfg.Limit,
Offset: cfg.Offset,
Filter: &models.QualificationFilter{
Filter: &model.QualificationFilter{
ID: qualificationIDs,
},
Count: cfg.Count,
})
}
func (repo *pgRepository) associateQualificationWithProfession(tx *pg.Tx, qualificationIDs, professionIDs []int) error {
var toInsert []*models.QualificationToProfession
func (repo *PGRepository) associateQualificationWithProfession(tx *pg.Tx, qualificationIDs, professionIDs []int) error {
var toInsert []*model.QualificationToProfession
for _, professionID := range professionIDs {
for _, qualificationID := range qualificationIDs {
toInsert = append(toInsert, &models.QualificationToProfession{
toInsert = append(toInsert, &model.QualificationToProfession{
ProfessionID: professionID,
QualificationID: qualificationID,
})

View File

@ -3,15 +3,15 @@ package qualification
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type Usecase interface {
Store(ctx context.Context, input *models.QualificationInput) (*models.Qualification, error)
UpdateOneByID(ctx context.Context, id int, input *models.QualificationInput) (*models.Qualification, error)
Delete(ctx context.Context, f *models.QualificationFilter) ([]*models.Qualification, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Qualification, int, error)
GetByID(ctx context.Context, id int) (*models.Qualification, error)
GetBySlug(ctx context.Context, slug string) (*models.Qualification, error)
GetSimilar(ctx context.Context, cfg *GetSimilarConfig) ([]*models.Qualification, int, error)
Store(ctx context.Context, input *model.QualificationInput) (*model.Qualification, error)
UpdateOneByID(ctx context.Context, id int, input *model.QualificationInput) (*model.Qualification, error)
Delete(ctx context.Context, f *model.QualificationFilter) ([]*model.Qualification, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.Qualification, int, error)
GetByID(ctx context.Context, id int) (*model.Qualification, error)
GetBySlug(ctx context.Context, slug string) (*model.Qualification, error)
GetSimilar(ctx context.Context, cfg *GetSimilarConfig) ([]*model.Qualification, int, error)
}

View File

@ -4,35 +4,37 @@ import (
"context"
"github.com/pkg/errors"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/qualification"
)
type usecase struct {
qualificationRepository qualification.Repository
}
type Config struct {
QualificationRepository qualification.Repository
}
func New(cfg *Config) (qualification.Usecase, error) {
type Usecase struct {
qualificationRepository qualification.Repository
}
var _ qualification.Usecase = &Usecase{}
func New(cfg *Config) (*Usecase, error) {
if cfg == nil || cfg.QualificationRepository == nil {
return nil, errors.New("cfg.QualificationRepository is required")
}
return &usecase{
return &Usecase{
cfg.QualificationRepository,
}, nil
}
func (ucase *usecase) Store(ctx context.Context, input *models.QualificationInput) (*models.Qualification, error) {
func (ucase *Usecase) Store(ctx context.Context, input *model.QualificationInput) (*model.Qualification, error) {
if err := validateInput(input.Sanitize(), validateOptions{false}); err != nil {
return nil, err
}
return ucase.qualificationRepository.Store(ctx, input)
}
func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.QualificationInput) (*models.Qualification, error) {
func (ucase *Usecase) UpdateOneByID(ctx context.Context, id int, input *model.QualificationInput) (*model.Qualification, error) {
if id <= 0 {
return nil, errors.New(messageInvalidID)
}
@ -40,7 +42,7 @@ func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.Q
return nil, err
}
items, err := ucase.qualificationRepository.UpdateMany(ctx,
&models.QualificationFilter{
&model.QualificationFilter{
ID: []int{id},
},
input)
@ -53,11 +55,11 @@ func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.Q
return items[0], nil
}
func (ucase *usecase) Delete(ctx context.Context, f *models.QualificationFilter) ([]*models.Qualification, error) {
func (ucase *Usecase) Delete(ctx context.Context, f *model.QualificationFilter) ([]*model.Qualification, error) {
return ucase.qualificationRepository.Delete(ctx, f)
}
func (ucase *usecase) Fetch(ctx context.Context, cfg *qualification.FetchConfig) ([]*models.Qualification, int, error) {
func (ucase *Usecase) Fetch(ctx context.Context, cfg *qualification.FetchConfig) ([]*model.Qualification, int, error) {
if cfg == nil {
cfg = &qualification.FetchConfig{
Limit: qualification.FetchDefaultLimit,
@ -70,11 +72,11 @@ func (ucase *usecase) Fetch(ctx context.Context, cfg *qualification.FetchConfig)
return ucase.qualificationRepository.Fetch(ctx, cfg)
}
func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.Qualification, error) {
func (ucase *Usecase) GetByID(ctx context.Context, id int) (*model.Qualification, error) {
items, _, err := ucase.Fetch(ctx, &qualification.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.QualificationFilter{
Filter: &model.QualificationFilter{
ID: []int{id},
},
})
@ -87,11 +89,11 @@ func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.Qualificatio
return items[0], nil
}
func (ucase *usecase) GetBySlug(ctx context.Context, slug string) (*models.Qualification, error) {
func (ucase *Usecase) GetBySlug(ctx context.Context, slug string) (*model.Qualification, error) {
items, _, err := ucase.Fetch(ctx, &qualification.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.QualificationFilter{
Filter: &model.QualificationFilter{
Slug: []string{slug},
},
})
@ -104,7 +106,7 @@ func (ucase *usecase) GetBySlug(ctx context.Context, slug string) (*models.Quali
return items[0], nil
}
func (ucase *usecase) GetSimilar(ctx context.Context, cfg *qualification.GetSimilarConfig) ([]*models.Qualification, int, error) {
func (ucase *Usecase) GetSimilar(ctx context.Context, cfg *qualification.GetSimilarConfig) ([]*model.Qualification, int, error) {
if cfg == nil || cfg.QualificationID <= 0 {
return nil, 0, errors.New(messageQualificationIDIsRequired)
}
@ -115,7 +117,7 @@ type validateOptions struct {
allowNilValues bool
}
func validateInput(input *models.QualificationInput, opts validateOptions) error {
func validateInput(input *model.QualificationInput, opts validateOptions) error {
if input.IsEmpty() {
return errors.New(messageEmptyPayload)
}

View File

@ -3,11 +3,11 @@ package question
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type FetchConfig struct {
Filter *models.QuestionFilter
Filter *model.QuestionFilter
Offset int
Limit int
Sort []string
@ -20,9 +20,9 @@ type GenerateTestConfig struct {
}
type Repository interface {
Store(ctx context.Context, input *models.QuestionInput) (*models.Question, error)
UpdateOneByID(ctx context.Context, id int, input *models.QuestionInput) (*models.Question, error)
Delete(ctx context.Context, f *models.QuestionFilter) ([]*models.Question, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Question, int, error)
GenerateTest(ctx context.Context, cfg *GenerateTestConfig) ([]*models.Question, error)
Store(ctx context.Context, input *model.QuestionInput) (*model.Question, error)
UpdateOneByID(ctx context.Context, id int, input *model.QuestionInput) (*model.Question, error)
Delete(ctx context.Context, f *model.QuestionFilter) ([]*model.Question, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.Question, int, error)
GenerateTest(ctx context.Context, cfg *GenerateTestConfig) ([]*model.Question, error)
}

View File

@ -8,30 +8,33 @@ import (
"time"
"github.com/go-pg/pg/v10"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/question"
"github.com/zdam-egzamin-zawodowy/backend/pkg/fstorage"
"github.com/zdam-egzamin-zawodowy/backend/pkg/util/errorutil"
)
type pgRepository struct {
*pg.DB
*repository
}
type PGRepositoryConfig struct {
DB *pg.DB
FileStorage fstorage.FileStorage
}
func NewPGRepository(cfg *PGRepositoryConfig) (question.Repository, error) {
type PGRepository struct {
*pg.DB
*repository
}
var _ question.Repository = &PGRepository{}
func NewPGRepository(cfg *PGRepositoryConfig) (*PGRepository, error) {
if cfg == nil || cfg.DB == nil {
return nil, errors.New("cfg.DB is required")
}
if cfg.FileStorage == nil {
return nil, errors.New("cfg.FileStorage is required")
}
return &pgRepository{
return &PGRepository{
cfg.DB,
&repository{
fileStorage: cfg.FileStorage,
@ -39,7 +42,7 @@ func NewPGRepository(cfg *PGRepositoryConfig) (question.Repository, error) {
}, nil
}
func (repo *pgRepository) Store(ctx context.Context, input *models.QuestionInput) (*models.Question, error) {
func (repo *PGRepository) Store(ctx context.Context, input *model.QuestionInput) (*model.Question, error) {
item := input.ToQuestion()
baseQuery := repo.
Model(item).
@ -67,8 +70,8 @@ func (repo *pgRepository) Store(ctx context.Context, input *models.QuestionInput
return item, nil
}
func (repo *pgRepository) UpdateOneByID(ctx context.Context, id int, input *models.QuestionInput) (*models.Question, error) {
item := &models.Question{}
func (repo *PGRepository) UpdateOneByID(ctx context.Context, id int, input *model.QuestionInput) (*model.Question, error) {
item := &model.Question{}
baseQuery := repo.
Model(item).
Context(ctx).
@ -100,8 +103,8 @@ func (repo *pgRepository) UpdateOneByID(ctx context.Context, id int, input *mode
return item, nil
}
func (repo *pgRepository) Delete(ctx context.Context, f *models.QuestionFilter) ([]*models.Question, error) {
items := make([]*models.Question, 0)
func (repo *PGRepository) Delete(ctx context.Context, f *model.QuestionFilter) ([]*model.Question, error) {
items := make([]*model.Question, 0)
if _, err := repo.
Model(&items).
Context(ctx).
@ -116,9 +119,9 @@ func (repo *pgRepository) Delete(ctx context.Context, f *models.QuestionFilter)
return items, nil
}
func (repo *pgRepository) Fetch(ctx context.Context, cfg *question.FetchConfig) ([]*models.Question, int, error) {
func (repo *PGRepository) Fetch(ctx context.Context, cfg *question.FetchConfig) ([]*model.Question, int, error) {
var err error
items := make([]*models.Question, 0)
items := make([]*model.Question, 0)
total := 0
query := repo.
Model(&items).
@ -141,14 +144,14 @@ func (repo *pgRepository) Fetch(ctx context.Context, cfg *question.FetchConfig)
return items, total, nil
}
func (repo *pgRepository) GenerateTest(ctx context.Context, cfg *question.GenerateTestConfig) ([]*models.Question, error) {
func (repo *PGRepository) GenerateTest(ctx context.Context, cfg *question.GenerateTestConfig) ([]*model.Question, error) {
subquery := repo.
Model(&models.Question{}).
Model(&model.Question{}).
Column("id").
Where(gopgutil.BuildConditionArray("qualification_id"), pg.Array(cfg.Qualifications)).
OrderExpr("random()").
Limit(cfg.Limit)
items := make([]*models.Question, 0)
items := make([]*model.Question, 0)
if err := repo.
Model(&items).
Context(ctx).

View File

@ -1,11 +1,13 @@
package repository
import (
"github.com/zdam-egzamin-zawodowy/backend/pkg/fstorage/fstorageutil"
"path/filepath"
"github.com/zdam-egzamin-zawodowy/backend/pkg/fstorage/fstorageutil"
"github.com/99designs/gqlgen/graphql"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/pkg/fstorage"
)
@ -13,7 +15,7 @@ type repository struct {
fileStorage fstorage.FileStorage
}
func (repo *repository) saveImages(destination *models.Question, input *models.QuestionInput) {
func (repo *repository) saveImages(destination *model.Question, input *model.QuestionInput) {
images := [...]*graphql.Upload{
input.Image,
input.AnswerAImage,
@ -56,7 +58,7 @@ func (repo *repository) deleteImages(images []string) {
}
}
func (repo *repository) deleteImagesBasedOnInput(question *models.Question, input *models.QuestionInput) {
func (repo *repository) deleteImagesBasedOnInput(question *model.Question, input *model.QuestionInput) {
images := []string{}
if input.DeleteImage != nil &&
@ -102,7 +104,7 @@ func (repo *repository) deleteImagesBasedOnInput(question *models.Question, inpu
repo.deleteImages(images)
}
func (repo *repository) getAllImagesAndDelete(questions []*models.Question) {
func (repo *repository) getAllImagesAndDelete(questions []*model.Question) {
images := []string{}
for _, question := range questions {

View File

@ -3,14 +3,14 @@ package question
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type Usecase interface {
Store(ctx context.Context, input *models.QuestionInput) (*models.Question, error)
UpdateOneByID(ctx context.Context, id int, input *models.QuestionInput) (*models.Question, error)
Delete(ctx context.Context, f *models.QuestionFilter) ([]*models.Question, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Question, int, error)
GetByID(ctx context.Context, id int) (*models.Question, error)
GenerateTest(ctx context.Context, cfg *GenerateTestConfig) ([]*models.Question, error)
Store(ctx context.Context, input *model.QuestionInput) (*model.Question, error)
UpdateOneByID(ctx context.Context, id int, input *model.QuestionInput) (*model.Question, error)
Delete(ctx context.Context, f *model.QuestionFilter) ([]*model.Question, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.Question, int, error)
GetByID(ctx context.Context, id int) (*model.Question, error)
GenerateTest(ctx context.Context, cfg *GenerateTestConfig) ([]*model.Question, error)
}

View File

@ -4,7 +4,7 @@ import (
"context"
"github.com/pkg/errors"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/question"
)
@ -16,31 +16,33 @@ var (
}
)
type usecase struct {
questionRepository question.Repository
}
type Config struct {
QuestionRepository question.Repository
}
func New(cfg *Config) (question.Usecase, error) {
type Usecase struct {
questionRepository question.Repository
}
var _ question.Usecase = &Usecase{}
func New(cfg *Config) (*Usecase, error) {
if cfg == nil || cfg.QuestionRepository == nil {
return nil, errors.New("cfg.QuestionRepository is required")
}
return &usecase{
return &Usecase{
cfg.QuestionRepository,
}, nil
}
func (ucase *usecase) Store(ctx context.Context, input *models.QuestionInput) (*models.Question, error) {
func (ucase *Usecase) Store(ctx context.Context, input *model.QuestionInput) (*model.Question, error) {
if err := validateInput(input.Sanitize(), validateOptions{false}); err != nil {
return nil, err
}
return ucase.questionRepository.Store(ctx, input)
}
func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.QuestionInput) (*models.Question, error) {
func (ucase *Usecase) UpdateOneByID(ctx context.Context, id int, input *model.QuestionInput) (*model.Question, error) {
if id <= 0 {
return nil, errors.New(messageInvalidID)
}
@ -59,11 +61,11 @@ func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.Q
return item, nil
}
func (ucase *usecase) Delete(ctx context.Context, f *models.QuestionFilter) ([]*models.Question, error) {
func (ucase *Usecase) Delete(ctx context.Context, f *model.QuestionFilter) ([]*model.Question, error) {
return ucase.questionRepository.Delete(ctx, f)
}
func (ucase *usecase) Fetch(ctx context.Context, cfg *question.FetchConfig) ([]*models.Question, int, error) {
func (ucase *Usecase) Fetch(ctx context.Context, cfg *question.FetchConfig) ([]*model.Question, int, error) {
if cfg == nil {
cfg = &question.FetchConfig{
Limit: question.FetchMaxLimit,
@ -79,11 +81,11 @@ func (ucase *usecase) Fetch(ctx context.Context, cfg *question.FetchConfig) ([]*
return ucase.questionRepository.Fetch(ctx, cfg)
}
func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.Question, error) {
func (ucase *Usecase) GetByID(ctx context.Context, id int) (*model.Question, error) {
items, _, err := ucase.Fetch(ctx, &question.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.QuestionFilter{
Filter: &model.QuestionFilter{
ID: []int{id},
},
})
@ -96,7 +98,7 @@ func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.Question, er
return items[0], nil
}
func (ucase *usecase) GenerateTest(ctx context.Context, cfg *question.GenerateTestConfig) ([]*models.Question, error) {
func (ucase *Usecase) GenerateTest(ctx context.Context, cfg *question.GenerateTestConfig) ([]*model.Question, error) {
if cfg == nil {
cfg = &question.GenerateTestConfig{
Limit: question.TestMaxLimit,
@ -112,7 +114,7 @@ type validateOptions struct {
allowNilValues bool
}
func validateInput(input *models.QuestionInput, opts validateOptions) error {
func validateInput(input *model.QuestionInput, opts validateOptions) error {
if input.IsEmpty() {
return errors.New(messageEmptyPayload)
}

View File

@ -3,11 +3,11 @@ package user
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type FetchConfig struct {
Filter *models.UserFilter
Filter *model.UserFilter
Offset int
Limit int
Sort []string
@ -15,8 +15,8 @@ type FetchConfig struct {
}
type Repository interface {
Store(ctx context.Context, input *models.UserInput) (*models.User, error)
UpdateMany(ctx context.Context, f *models.UserFilter, input *models.UserInput) ([]*models.User, error)
Delete(ctx context.Context, f *models.UserFilter) ([]*models.User, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.User, int, error)
Store(ctx context.Context, input *model.UserInput) (*model.User, error)
UpdateMany(ctx context.Context, f *model.UserFilter, input *model.UserInput) ([]*model.User, error)
Delete(ctx context.Context, f *model.UserFilter) ([]*model.User, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.User, int, error)
}

View File

@ -9,28 +9,31 @@ import (
"github.com/zdam-egzamin-zawodowy/backend/pkg/util/errorutil"
"github.com/go-pg/pg/v10"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/user"
)
type pgRepository struct {
*pg.DB
}
type PGRepositoryConfig struct {
DB *pg.DB
}
func NewPGRepository(cfg *PGRepositoryConfig) (user.Repository, error) {
type PGRepository struct {
*pg.DB
}
var _ user.Repository = &PGRepository{}
func NewPGRepository(cfg *PGRepositoryConfig) (*PGRepository, error) {
if cfg == nil || cfg.DB == nil {
return nil, errors.New("cfg.DB is required")
}
return &pgRepository{
return &PGRepository{
cfg.DB,
}, nil
}
func (repo *pgRepository) Store(ctx context.Context, input *models.UserInput) (*models.User, error) {
func (repo *PGRepository) Store(ctx context.Context, input *model.UserInput) (*model.User, error) {
item := input.ToUser()
if _, err := repo.
Model(item).
@ -42,9 +45,9 @@ func (repo *pgRepository) Store(ctx context.Context, input *models.UserInput) (*
return item, nil
}
func (repo *pgRepository) UpdateMany(ctx context.Context, f *models.UserFilter, input *models.UserInput) ([]*models.User, error) {
func (repo *PGRepository) UpdateMany(ctx context.Context, f *model.UserFilter, input *model.UserInput) ([]*model.User, error) {
if _, err := repo.
Model(&models.User{}).
Model(&model.User{}).
Context(ctx).
Apply(input.ApplyUpdate).
Apply(f.Where).
@ -61,8 +64,8 @@ func (repo *pgRepository) UpdateMany(ctx context.Context, f *models.UserFilter,
return items, nil
}
func (repo *pgRepository) Delete(ctx context.Context, f *models.UserFilter) ([]*models.User, error) {
items := make([]*models.User, 0)
func (repo *PGRepository) Delete(ctx context.Context, f *model.UserFilter) ([]*model.User, error) {
items := make([]*model.User, 0)
if _, err := repo.
Model(&items).
Context(ctx).
@ -74,9 +77,9 @@ func (repo *pgRepository) Delete(ctx context.Context, f *models.UserFilter) ([]*
return items, nil
}
func (repo *pgRepository) Fetch(ctx context.Context, cfg *user.FetchConfig) ([]*models.User, int, error) {
func (repo *PGRepository) Fetch(ctx context.Context, cfg *user.FetchConfig) ([]*model.User, int, error) {
var err error
items := make([]*models.User, 0)
items := make([]*model.User, 0)
total := 0
query := repo.
Model(&items).

View File

@ -3,15 +3,15 @@ package user
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
)
type Usecase interface {
Store(ctx context.Context, input *models.UserInput) (*models.User, error)
UpdateOneByID(ctx context.Context, id int, input *models.UserInput) (*models.User, error)
UpdateMany(ctx context.Context, f *models.UserFilter, input *models.UserInput) ([]*models.User, error)
Delete(ctx context.Context, f *models.UserFilter) ([]*models.User, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.User, int, error)
GetByID(ctx context.Context, id int) (*models.User, error)
GetByCredentials(ctx context.Context, email, password string) (*models.User, error)
Store(ctx context.Context, input *model.UserInput) (*model.User, error)
UpdateOneByID(ctx context.Context, id int, input *model.UserInput) (*model.User, error)
UpdateMany(ctx context.Context, f *model.UserFilter, input *model.UserInput) ([]*model.User, error)
Delete(ctx context.Context, f *model.UserFilter) ([]*model.User, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*model.User, int, error)
GetByID(ctx context.Context, id int) (*model.User, error)
GetByCredentials(ctx context.Context, email, password string) (*model.User, error)
}

View File

@ -5,41 +5,43 @@ import (
"github.com/Kichiyaki/goutil/strutil"
"github.com/pkg/errors"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/model"
"github.com/zdam-egzamin-zawodowy/backend/internal/user"
)
type usecase struct {
userRepository user.Repository
}
type Config struct {
UserRepository user.Repository
}
func New(cfg *Config) (user.Usecase, error) {
type Usecase struct {
userRepository user.Repository
}
var _ user.Usecase = &Usecase{}
func New(cfg *Config) (*Usecase, error) {
if cfg == nil || cfg.UserRepository == nil {
return nil, errors.New("cfg.UserRepository is required")
}
return &usecase{
return &Usecase{
cfg.UserRepository,
}, nil
}
func (ucase *usecase) Store(ctx context.Context, input *models.UserInput) (*models.User, error) {
func (ucase *Usecase) Store(ctx context.Context, input *model.UserInput) (*model.User, error) {
if err := validateInput(input.Sanitize(), validateOptions{false}); err != nil {
return nil, err
}
return ucase.userRepository.Store(ctx, input)
}
func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.UserInput) (*models.User, error) {
func (ucase *Usecase) UpdateOneByID(ctx context.Context, id int, input *model.UserInput) (*model.User, error) {
if id <= 0 {
return nil, errors.New(messageInvalidID)
}
items, err := ucase.UpdateMany(
ctx,
&models.UserFilter{
&model.UserFilter{
ID: []int{id},
},
input.Sanitize(),
@ -53,9 +55,9 @@ func (ucase *usecase) UpdateOneByID(ctx context.Context, id int, input *models.U
return items[0], nil
}
func (ucase *usecase) UpdateMany(ctx context.Context, f *models.UserFilter, input *models.UserInput) ([]*models.User, error) {
func (ucase *Usecase) UpdateMany(ctx context.Context, f *model.UserFilter, input *model.UserInput) ([]*model.User, error) {
if f == nil {
return []*models.User{}, nil
return []*model.User{}, nil
}
if err := validateInput(input.Sanitize(), validateOptions{true}); err != nil {
return nil, err
@ -67,11 +69,11 @@ func (ucase *usecase) UpdateMany(ctx context.Context, f *models.UserFilter, inpu
return items, nil
}
func (ucase *usecase) Delete(ctx context.Context, f *models.UserFilter) ([]*models.User, error) {
func (ucase *Usecase) Delete(ctx context.Context, f *model.UserFilter) ([]*model.User, error) {
return ucase.userRepository.Delete(ctx, f)
}
func (ucase *usecase) Fetch(ctx context.Context, cfg *user.FetchConfig) ([]*models.User, int, error) {
func (ucase *Usecase) Fetch(ctx context.Context, cfg *user.FetchConfig) ([]*model.User, int, error) {
if cfg == nil {
cfg = &user.FetchConfig{
Limit: user.FetchMaxLimit,
@ -87,11 +89,11 @@ func (ucase *usecase) Fetch(ctx context.Context, cfg *user.FetchConfig) ([]*mode
return ucase.userRepository.Fetch(ctx, cfg)
}
func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.User, error) {
func (ucase *Usecase) GetByID(ctx context.Context, id int) (*model.User, error) {
items, _, err := ucase.Fetch(ctx, &user.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.UserFilter{
Filter: &model.UserFilter{
ID: []int{id},
},
})
@ -104,11 +106,11 @@ func (ucase *usecase) GetByID(ctx context.Context, id int) (*models.User, error)
return items[0], nil
}
func (ucase *usecase) GetByCredentials(ctx context.Context, email, password string) (*models.User, error) {
func (ucase *Usecase) GetByCredentials(ctx context.Context, email, password string) (*model.User, error) {
items, _, err := ucase.Fetch(ctx, &user.FetchConfig{
Limit: 1,
Count: false,
Filter: &models.UserFilter{
Filter: &model.UserFilter{
Email: []string{email},
},
})
@ -128,7 +130,7 @@ type validateOptions struct {
acceptNilValues bool
}
func validateInput(input *models.UserInput, opts validateOptions) error {
func validateInput(input *model.UserInput, opts validateOptions) error {
if input.IsEmpty() {
return errors.New(messageEmptyPayload)
}