cleanup: refactor api architecture & add user roles
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
generate:
|
||||
rm graph/schema.graphqls
|
||||
for f in graph/schema/*.gql; do cat $f; echo; done > graph/schema.graphqls
|
||||
|
||||
start:
|
||||
docker container start test-db
|
||||
go run cmd/citadel/main.go
|
||||
|
@ -3,20 +3,50 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
_ "github.com/lib/pq"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/jordanknott/project-citadel/api/router"
|
||||
"github.com/jordanknott/project-citadel/api/internal/route"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
Host string
|
||||
Name string
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
type AppConfig struct {
|
||||
Database Database
|
||||
}
|
||||
|
||||
func main() {
|
||||
dat, err := ioutil.ReadFile("conf/app.toml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var appConfig AppConfig
|
||||
_, err = toml.Decode(string(dat), &appConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Formatter := new(log.TextFormatter)
|
||||
Formatter.TimestampFormat = "02-01-2006 15:04:05"
|
||||
Formatter.FullTimestamp = true
|
||||
log.SetFormatter(Formatter)
|
||||
db, err := sqlx.Connect("postgres", "user=postgres password=test host=0.0.0.0 dbname=citadel sslmode=disable")
|
||||
log.SetLevel(log.InfoLevel)
|
||||
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
|
||||
appConfig.Database.User,
|
||||
appConfig.Database.Password,
|
||||
appConfig.Database.Host,
|
||||
appConfig.Database.Name,
|
||||
)
|
||||
db, err := sqlx.Connect("postgres", connection)
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
@ -27,6 +57,6 @@ func main() {
|
||||
defer db.Close()
|
||||
fmt.Println("starting graphql server on http://localhost:3333")
|
||||
fmt.Println("starting graphql playground on http://localhost:3333/__graphql")
|
||||
r, _ := router.NewRouter(db)
|
||||
r, _ := route.NewRouter(db)
|
||||
http.ListenAndServe(":3333", r)
|
||||
}
|
||||
|
@ -1,20 +1,43 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
// "context"
|
||||
// "fmt"
|
||||
// "io/ioutil"
|
||||
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/jordan-wright/email"
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
"github.com/jordanknott/project-citadel/api/router"
|
||||
_ "github.com/lib/pq"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"io/ioutil"
|
||||
"net/smtp"
|
||||
// "github.com/jmoiron/sqlx"
|
||||
// "github.com/jordanknott/project-citadel/api/pg"
|
||||
// "github.com/BurntSushi/toml"
|
||||
// "github.com/jordanknott/project-citadel/api/router"
|
||||
// "time"
|
||||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
)
|
||||
|
||||
type Database struct {
|
||||
Host string
|
||||
Name string
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
type AppConfig struct {
|
||||
Database Database
|
||||
}
|
||||
|
||||
type UserRegistration struct {
|
||||
Username string
|
||||
Year string
|
||||
AppName string
|
||||
AppURL string
|
||||
}
|
||||
|
||||
type color struct {
|
||||
Name string
|
||||
Color string
|
||||
@ -25,39 +48,136 @@ type colors struct {
|
||||
Color []color
|
||||
}
|
||||
|
||||
func main() {
|
||||
func SendEmail() {
|
||||
emailTmpl, err := ioutil.ReadFile("templates/mail/user/registered.tmpl")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
user := UserRegistration{Username: "jordanthedev", AppName: "Citadel", AppURL: "http://localhost:3000/", Year: "2020"}
|
||||
tmpl, err := template.New("registered").Parse(string(emailTmpl))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var tpl bytes.Buffer
|
||||
if err := tmpl.Execute(&tpl, &user); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
result := tpl.String()
|
||||
|
||||
e := email.NewEmail()
|
||||
e.From = "Jordan Knott <no-reply@citadel.com>"
|
||||
e.To = []string{"jordan@jordanthedev.com"}
|
||||
e.Subject = "Jordan Knott (@jordanthedev) invited you to join the team \"Paradox\" on Citadel"
|
||||
e.Text = []byte("Text Body is, of course, supported!")
|
||||
e.HTML = []byte("<h1>Fancy HTML is supported, too!</h1>")
|
||||
e.HTML = []byte(result)
|
||||
e.Send("localhost:1025", smtp.PlainAuth("", "test@gmail.com", "password123", "localhost"))
|
||||
// dur := time.Hour * 24 * 7 * 30
|
||||
// token, err := router.NewAccessTokenCustomExpiration("21345076-6423-4a00-a6bd-cd9f830e2764", dur)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// fmt.Println(token)
|
||||
|
||||
// fmt.Println("seeding database...")
|
||||
|
||||
// dat, err := ioutil.ReadFile("data/colors.toml")
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
|
||||
// var labelColors colors
|
||||
// _, err = toml.Decode(string(dat), &labelColors)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// db, err := sqlx.Connect("postgres", "user=postgres password=test host=0.0.0.0 dbname=citadel sslmode=disable")
|
||||
// repository := pg.NewRepository(db)
|
||||
// for _, color := range labelColors.Color {
|
||||
// fmt.Printf("%v\n", color)
|
||||
// repository.CreateLabelColor(context.Background(), pg.CreateLabelColorParams{color.Name, color.Color, float64(color.Position)})
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
func Seed() {
|
||||
dur := time.Hour * 24 * 7 * 30
|
||||
token, err := router.NewAccessTokenCustomExpiration("21345076-6423-4a00-a6bd-cd9f830e2764", dur)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(token)
|
||||
|
||||
fmt.Println("seeding database...")
|
||||
|
||||
dat, err := ioutil.ReadFile("data/dark_colors.toml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var labelColors colors
|
||||
_, err = toml.Decode(string(dat), &labelColors)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
db, err := sqlx.Connect("postgres", "user=postgres password=test host=0.0.0.0 dbname=citadel sslmode=disable")
|
||||
repository := pg.NewRepository(db)
|
||||
for _, color := range labelColors.Color {
|
||||
fmt.Printf("%v\n", color)
|
||||
repository.CreateLabelColor(context.Background(), pg.CreateLabelColorParams{color.Name, color.Color, float64(color.Position)})
|
||||
}
|
||||
}
|
||||
func Migrate() {
|
||||
dat, err := ioutil.ReadFile("conf/app.toml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var appConfig AppConfig
|
||||
_, err = toml.Decode(string(dat), &appConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
|
||||
appConfig.Database.User,
|
||||
appConfig.Database.Password,
|
||||
appConfig.Database.Host,
|
||||
appConfig.Database.Name,
|
||||
)
|
||||
fmt.Println(connection)
|
||||
db, err := sqlx.Connect("postgres", connection)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer db.Close()
|
||||
driver, err := postgres.WithInstance(db.DB, &postgres.Config{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
m, err := migrate.NewWithDatabaseInstance(
|
||||
"file://migrations",
|
||||
"postgres", driver)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = m.Up()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
func main() {
|
||||
dat, err := ioutil.ReadFile("conf/app.toml")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var appConfig AppConfig
|
||||
_, err = toml.Decode(string(dat), &appConfig)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
|
||||
appConfig.Database.User,
|
||||
appConfig.Database.Password,
|
||||
appConfig.Database.Host,
|
||||
appConfig.Database.Name,
|
||||
)
|
||||
fmt.Println(connection)
|
||||
db, err := sqlx.Connect("postgres", connection)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
}
|
||||
createdAt := time.Now().UTC()
|
||||
hashedPwd, err := bcrypt.GenerateFromPassword([]byte("test"), 14)
|
||||
repo := pg.NewRepository(db)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = repo.CreateUserAccount(context.Background(), pg.CreateUserAccountParams{
|
||||
Username: "jordan",
|
||||
Initials: "JK",
|
||||
Email: "jordan@jordanthedev.com",
|
||||
PasswordHash: string(hashedPwd),
|
||||
CreatedAt: createdAt,
|
||||
RoleCode: "admin",
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
56
api/cmd/send/main.go
Normal file
56
api/cmd/send/main.go
Normal file
@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
"github.com/RichardKnop/machinery/v1/config"
|
||||
"github.com/RichardKnop/machinery/v1/tasks"
|
||||
)
|
||||
|
||||
func Add(args ...int64) (int64, error) {
|
||||
sum := int64(0)
|
||||
for _, arg := range args {
|
||||
sum += arg
|
||||
}
|
||||
return sum, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var cnf = &config.Config{
|
||||
Broker: "amqp://guest:guest@localhost:5672/",
|
||||
DefaultQueue: "machinery_tasks",
|
||||
ResultBackend: "memcache://localhost:11211",
|
||||
AMQP: &config.AMQPConfig{
|
||||
Exchange: "machinery_exchange",
|
||||
ExchangeType: "direct",
|
||||
BindingKey: "machinery_task",
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Println("starting server")
|
||||
server, err := machinery.NewServer(cnf)
|
||||
if err != nil {
|
||||
// do something with the error
|
||||
}
|
||||
|
||||
addTask0 := tasks.Signature{
|
||||
Name: "userRegistration",
|
||||
Args: []tasks.Arg{
|
||||
{
|
||||
Type: "string",
|
||||
Value: "21345076-6423-4a00-a6bd-cd9f830e2764",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
asyncResult, err := server.SendTask(&addTask0)
|
||||
if err != nil {
|
||||
fmt.Errorf("Could not send task: %s", err.Error())
|
||||
}
|
||||
fmt.Println(asyncResult.GetState())
|
||||
|
||||
// results, err := asyncResult.Get(time.Duration(time.Millisecond * 5))
|
||||
// fmt.Printf("split([\"foo\"]) = %v\n", tasks.HumanReadableResults(results))
|
||||
|
||||
}
|
66
api/cmd/worker/main.go
Normal file
66
api/cmd/worker/main.go
Normal file
@ -0,0 +1,66 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
"github.com/RichardKnop/machinery/v1/config"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
type MachineTasks struct {
|
||||
Repository pg.Repository
|
||||
}
|
||||
|
||||
func (m *MachineTasks) UserRegistration(userID string) (bool, error) {
|
||||
ctx := context.Background()
|
||||
uid, err := uuid.Parse(userID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
user, err := m.Repository.GetUserAccountByID(ctx, uid)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if user.Username == "jordan" {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var cnf = &config.Config{
|
||||
Broker: "amqp://guest:guest@localhost:5672/",
|
||||
DefaultQueue: "machinery_tasks",
|
||||
ResultBackend: "memcache://localhost:11211",
|
||||
AMQP: &config.AMQPConfig{
|
||||
Exchange: "machinery_exchange",
|
||||
ExchangeType: "direct",
|
||||
BindingKey: "machinery_task",
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Println("starting server")
|
||||
server, err := machinery.NewServer(cnf)
|
||||
if err != nil {
|
||||
// do something with the error
|
||||
}
|
||||
|
||||
db, err := sqlx.Connect("postgres", "user=postgres password=test host=0.0.0.0 dbname=citadel sslmode=disable")
|
||||
repo := pg.NewRepository(db)
|
||||
tasks := MachineTasks{repo}
|
||||
server.RegisterTasks(map[string]interface{}{
|
||||
"userRegistration": tasks.UserRegistration,
|
||||
})
|
||||
|
||||
worker := server.NewWorker("citadel_worker", 10)
|
||||
fmt.Println("launching worker")
|
||||
err = worker.Launch()
|
||||
if err != nil {
|
||||
// do something with the error
|
||||
}
|
||||
}
|
5
api/conf/app.toml
Normal file
5
api/conf/app.toml
Normal file
@ -0,0 +1,5 @@
|
||||
[database]
|
||||
host = '0.0.0.0'
|
||||
name = 'citadel'
|
||||
user = 'postgres'
|
||||
password = 'test'
|
74
api/data/dark_colors.toml
Normal file
74
api/data/dark_colors.toml
Normal file
@ -0,0 +1,74 @@
|
||||
[[color]]
|
||||
name = "red"
|
||||
color = '#e8384f'
|
||||
position = 1
|
||||
|
||||
[[color]]
|
||||
name = "orange"
|
||||
color = '#fd612c'
|
||||
position = 2
|
||||
|
||||
[[color]]
|
||||
name = "yellow_orange"
|
||||
color = '#fd9a00'
|
||||
position = 3
|
||||
|
||||
[[color]]
|
||||
name = "yellow"
|
||||
color = '#eec300'
|
||||
position = 4
|
||||
|
||||
[[color]]
|
||||
name = "yellow_green"
|
||||
color = '#a4cf30'
|
||||
position = 5
|
||||
|
||||
[[color]]
|
||||
name = "green"
|
||||
color = '#62d26f'
|
||||
position = 6
|
||||
|
||||
[[color]]
|
||||
name = "blue_green"
|
||||
color = '#37c5ab'
|
||||
position = 7
|
||||
|
||||
[[color]]
|
||||
name = "aqua"
|
||||
color = '#20aaea'
|
||||
position = 8
|
||||
|
||||
[[color]]
|
||||
name = "blue"
|
||||
color = '#4186e0'
|
||||
position = 9
|
||||
|
||||
[[color]]
|
||||
name = "indigo"
|
||||
color = '#7a6ff0'
|
||||
position = 10
|
||||
|
||||
[[color]]
|
||||
name = "purple"
|
||||
color = '#aa62e3'
|
||||
position = 11
|
||||
|
||||
[[color]]
|
||||
name = "magenta"
|
||||
color = '#e362e3'
|
||||
position = 12
|
||||
|
||||
[[color]]
|
||||
name = "hot_pink"
|
||||
color = '#ea4e9d'
|
||||
position = 13
|
||||
|
||||
[[color]]
|
||||
name = "pink"
|
||||
color = '#fc91ad'
|
||||
position = 14
|
||||
|
||||
[[color]]
|
||||
name = "cool_gray"
|
||||
color = '#8da3a6'
|
||||
position = 15
|
16
api/data/dark_colors.yml
Normal file
16
api/data/dark_colors.yml
Normal file
@ -0,0 +1,16 @@
|
||||
colors:
|
||||
red: '#e8384f'
|
||||
orange: '#fd612c'
|
||||
yellow_orange: '#fd9a00'
|
||||
yellow: '#eec300'
|
||||
yellow_green: '#a4cf30'
|
||||
green: '#62d26f'
|
||||
blue_green: '#37c5ab'
|
||||
aqua: '#20aaea'
|
||||
blue: '#4186e0'
|
||||
indigo: '#7a6ff0'
|
||||
purple: '#aa62e3'
|
||||
magenta: '#e362e3'
|
||||
hot_pink: '#ea4e9d'
|
||||
pink: '#fc91ad'
|
||||
cool_gray: '#8da3a6'
|
@ -6,3 +6,14 @@ services:
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 8025:8025
|
||||
broker:
|
||||
image: rabbitmq:3-management
|
||||
restart: always
|
||||
ports:
|
||||
- 8060:15672
|
||||
- 5672:5672
|
||||
result_store:
|
||||
image: memcached:1.6-alpine
|
||||
restart: always
|
||||
ports:
|
||||
- 11211:11211
|
||||
|
11
api/go.mod
11
api/go.mod
@ -5,25 +5,28 @@ go 1.13
|
||||
require (
|
||||
github.com/99designs/gqlgen v0.11.3
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/RichardKnop/machinery v1.8.6
|
||||
github.com/boyter/scc v2.12.0+incompatible // indirect
|
||||
github.com/dbaggerman/cuba v0.3.2 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/go-chi/chi v3.3.2+incompatible
|
||||
github.com/go-chi/cors v1.0.0
|
||||
github.com/golang-migrate/migrate/v4 v4.11.0
|
||||
github.com/google/martian v2.1.0+incompatible
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/jmoiron/sqlx v1.2.0
|
||||
github.com/jordan-wright/email v0.0.0-20200602115436-fd8a7622303e
|
||||
github.com/lib/pq v1.0.0
|
||||
github.com/lib/pq v1.3.0
|
||||
github.com/magefile/mage v1.9.0
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200525100937-58356a36e03f // indirect
|
||||
github.com/pelletier/go-toml v1.8.0
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/spf13/cobra v1.0.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/urfave/cli v1.20.0 // indirect
|
||||
github.com/streadway/amqp v1.0.0
|
||||
github.com/vektah/gqlparser/v2 v2.0.1
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
)
|
||||
|
476
api/go.sum
476
api/go.sum
@ -1,70 +1,217 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0 h1:MZQCQQaRwOrAcuKjiHWHrgKykt4fZyuwF2dtiG3fGW8=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/spanner v1.2.0/go.mod h1:LfwGAsK42Yz8IeLsd/oagGFBqTXt3xVWtm8/KD2vrEI=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/99designs/gqlgen v0.11.1 h1:QoSL8/AAJ2T3UOeQbdnBR32JcG4pO08+P/g5jdbFkUg=
|
||||
github.com/99designs/gqlgen v0.11.1/go.mod h1:vjFOyBZ7NwDl+GdSD4PFn7BQn5Fy7ohJwXn7Vk8zz+c=
|
||||
github.com/99designs/gqlgen v0.11.3 h1:oFSxl1DFS9X///uHV3y6CEfpcXWrDUxVblR4Xib2bs4=
|
||||
github.com/99designs/gqlgen v0.11.3/go.mod h1:RgX5GRRdDWNkh4pBrdzNpNPFVsdoUFY2+adM6nb1N+4=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/ClickHouse/clickhouse-go v1.3.12/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae h1:DcFpTQBYQ9Ct2d6sC7ol0/ynxc2pO1cpGUM+f4t5adg=
|
||||
github.com/RichardKnop/logging v0.0.0-20190827224416-1a693bdd4fae/go.mod h1:rJJ84PyA/Wlmw1hO+xTzV2wsSUon6J5ktg0g8BF2PuU=
|
||||
github.com/RichardKnop/machinery v1.8.6 h1:IPdPeO/yVE32isMJME2hiCgJgNibCVLjhshyjrQIDFY=
|
||||
github.com/RichardKnop/machinery v1.8.6/go.mod h1:W87mnh7t91WdrwGbdnAjvDzqD/bqBV+0+GF276gv/bU=
|
||||
github.com/RichardKnop/redsync v1.2.0 h1:gK35hR3zZkQigHKm8wOGb9MpJ9BsrW6MzxezwjTcHP0=
|
||||
github.com/RichardKnop/redsync v1.2.0/go.mod h1:9b8nBGAX3bE2uCfJGSnsDvF23mKyHTZzmvmj5FH3Tp0=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
|
||||
github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0=
|
||||
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.29.15 h1:0ms/213murpsujhsnxnNKNeVouW60aJqSd992Ks3mxs=
|
||||
github.com/aws/aws-sdk-go v1.29.15/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||
github.com/boyter/scc v2.12.0+incompatible h1:Sxhi1Ry3gdreoaF0xEITQSdjR+pJT0cXHXhlDw5FHT0=
|
||||
github.com/boyter/scc v2.12.0+incompatible/go.mod h1:VB5w4e0dahmIiKnpZ7LRh/sjauoY0BmCWjIzZcShNY0=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20190925194419-606b3d062051/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk=
|
||||
github.com/containerd/containerd v1.3.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/cznic/mathutil v0.0.0-20180504122225-ca4c9f2c1369/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dbaggerman/cuba v0.3.2 h1:6ZbQX3FNvkocR222YyoAIZ8wi4avrb7JcJkPvVI2AS4=
|
||||
github.com/dbaggerman/cuba v0.3.2/go.mod h1:t9Oo05XRZGcjaVqsA/gFeNAOm7DYZYNhI17unI5FlwY=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
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/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
|
||||
github.com/dhui/dktest v0.3.2/go.mod h1:l1/ib23a/CmxAe7yixtrYPc8Iy90Zy2udyaHINM5p58=
|
||||
github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v1.4.2-0.20200213202729-31a86c4ab209/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
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=
|
||||
github.com/fsouza/fake-gcs-server v1.17.0/go.mod h1:D1rTE4YCyHFNa99oyJJ5HyclvN/0uQR+pM/VdlL83bw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-chi/chi v3.3.2+incompatible h1:uQNcQN3NsV1j4ANsPh42P4ew4t6rnRbJb8frvpp31qQ=
|
||||
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-chi/cors v1.0.0 h1:e6x8k7uWbUwYs+aXDoiUzeQFT6l0cygBYyNhD7/1Tg0=
|
||||
github.com/go-chi/cors v1.0.0/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-redis/redis v6.15.7+incompatible h1:3skhDh95XQMpnqeqNftPkQD9jL9e5e36z/1SUm6dy1U=
|
||||
github.com/go-redis/redis v6.15.7+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||
github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY=
|
||||
github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg=
|
||||
github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
|
||||
github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs=
|
||||
github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI=
|
||||
github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk=
|
||||
github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28=
|
||||
github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo=
|
||||
github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk=
|
||||
github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw=
|
||||
github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360=
|
||||
github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg=
|
||||
github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE=
|
||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||
github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8=
|
||||
github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc=
|
||||
github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4=
|
||||
github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ=
|
||||
github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0=
|
||||
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
|
||||
github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhDUs8XyuhSVCVy52Jq3L+/3GJgYkwc+/0=
|
||||
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
github.com/golang-migrate/migrate v3.5.4+incompatible h1:R7OzwvCJTCgwapPCiX6DyBiu2czIUMDCB118gFTKTUA=
|
||||
github.com/golang-migrate/migrate/v4 v4.11.0 h1:uqtd0ysK5WyBQ/T1K2uDIooJV0o2Obt6uPwP062DupQ=
|
||||
github.com/golang-migrate/migrate/v4 v4.11.0/go.mod h1:nqbpDbckcYjsCD5I8q5+NI9Tkk7SVcmaF40Ax1eAWhg=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
|
||||
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
@ -72,39 +219,102 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.3.2/go.mod h1:LvCquS3HbBKwgl7KbX9KyqEIumJAbm1UMcTvGaIf3bM=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jordan-wright/email v0.0.0-20200602115436-fd8a7622303e h1:OGunVjqY7y4U4laftpEHv+mvZBlr7UGimJXKEGQtg48=
|
||||
github.com/jordan-wright/email v0.0.0-20200602115436-fd8a7622303e/go.mod h1:Fy2gCFfZhay8jplf/Csj6cyH/oshQTkLQYZbKkcV+SY=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
|
||||
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
|
||||
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.2 h1:Znfn6hXZAHaLPNnlqUYRrBSReFHYybslgv4PTiyz6P0=
|
||||
github.com/klauspost/compress v1.10.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
|
||||
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/magefile/mage v1.9.0 h1:t3AU2wNwehMCW97vuqQLtw6puppWXHO+O2MHo5a50XE=
|
||||
github.com/magefile/mage v1.9.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQDXbLhiuI=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007 h1:reVOUXwnhsYv/8UqjvhrMOu5CNT9UapHFLbQ2JcXsmg=
|
||||
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g=
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ=
|
||||
@ -115,44 +325,81 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200525100937-58356a36e03f h1:0HN0GKijN4mr9SmYoW/Ni3ozuNeHiSxo2s7drhv7obY=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200525100937-58356a36e03f/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
|
||||
github.com/neo4j-drivers/gobolt v1.7.4/go.mod h1:O9AUbip4Dgre+CD3p40dnMD4a4r52QBIfblg5k7CTbE=
|
||||
github.com/neo4j/neo4j-go-driver v1.7.4/go.mod h1:aPO0vVr+WnhEJne+FgFjfsjzAnssPFLucHgGZ76Zb/U=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||
github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw=
|
||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.3.0/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
@ -161,90 +408,319 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/streadway/amqp v0.0.0-20200108173154-1c71cc93ed71/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo=
|
||||
github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stvp/tempredis v0.0.0-20181119212430-b82af8480203/go.mod h1:oqN97ltKNihBbwlX8dLpwxCl3+HnXKV/R0e+sRLd9C8=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e h1:+w0Zm/9gaWpEAyDlU1eKOuk5twTjAjuevXqcJJw8hrg=
|
||||
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
|
||||
github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=
|
||||
github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
|
||||
github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.3.0 h1:ew6uUIeJOo+qdUUv7LxFCUhtWmVv7ZV/Xuy4FAUsw2E=
|
||||
go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200213203834-85f925bdd4d0/go.mod h1:IX6Eufr4L0ErOUlzqX/aFlHqsiKZRbV42Kb69e9VsTE=
|
||||
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
|
||||
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200128002243-345141a36859/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200213224642-88e652f7a869/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200303165918-5bcca83a7881/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0 h1:GwFK8+l5/gdsOYKz5p6M4UK+QT8OvmHWZPJCnf+5DjA=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200303153909-beee998c1893 h1:OTjq5CN+5TpMIvzqxSFCjbBX3jNKjX0XOPi4SdBxQU8=
|
||||
google.golang.org/genproto v0.0.0-20200303153909-beee998c1893/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7/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=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
|
||||
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
|
||||
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
|
||||
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM=
|
||||
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
|
||||
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
|
||||
|
@ -1,10 +1,10 @@
|
||||
# Where are all the schema files located? globs are supported eg src/**/*.graphqls
|
||||
schema:
|
||||
- graph/*.graphqls
|
||||
- internal/graph/schema.graphqls
|
||||
|
||||
# Where should the generated server code go?
|
||||
exec:
|
||||
filename: graph/generated.go
|
||||
filename: internal/graph/generated.go
|
||||
package: graph
|
||||
|
||||
# Uncomment to enable federation
|
||||
@ -14,7 +14,7 @@ exec:
|
||||
|
||||
# Where should any generated models go?
|
||||
model:
|
||||
filename: graph/models_gen.go
|
||||
filename: internal/graph/models_gen.go
|
||||
package: graph
|
||||
|
||||
# Where should the resolver implementations go?
|
||||
@ -29,7 +29,7 @@ omit_slice_element_pointers: true
|
||||
# gqlgen will search for any type names in the schema in these go packages
|
||||
# if they match it will use them, otherwise it will generate them.
|
||||
autobind:
|
||||
- "github.com/jordanknott/project-citadel/api/pg"
|
||||
- "github.com/jordanknott/project-citadel/api/internal/db"
|
||||
|
||||
# This section declares type mapping between the GraphQL and go type systems
|
||||
#
|
||||
@ -38,10 +38,10 @@ autobind:
|
||||
# your liking
|
||||
models:
|
||||
ID:
|
||||
model: github.com/jordanknott/project-citadel/api/graph.UUID
|
||||
model: github.com/jordanknott/project-citadel/api/internal/graph.UUID
|
||||
Int:
|
||||
model:
|
||||
- github.com/99designs/gqlgen/graphql.Int
|
||||
|
||||
UUID:
|
||||
model: github.com/jordanknott/project-citadel/api/graph.UUID
|
||||
model: github.com/jordanknott/project-citadel/api/internal/graph.UUID
|
||||
|
@ -1,4 +1,4 @@
|
||||
package router
|
||||
package auth
|
||||
|
||||
import (
|
||||
"time"
|
||||
@ -7,6 +7,30 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var jwtKey = []byte("citadel_test_key")
|
||||
|
||||
type AccessTokenClaims struct {
|
||||
UserID string `json:"userId"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type RefreshTokenClaims struct {
|
||||
UserID string `json:"userId"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type ErrExpiredToken struct{}
|
||||
|
||||
func (r *ErrExpiredToken) Error() string {
|
||||
return "token is expired"
|
||||
}
|
||||
|
||||
type ErrMalformedToken struct{}
|
||||
|
||||
func (r *ErrMalformedToken) Error() string {
|
||||
return "token is malformed"
|
||||
}
|
||||
|
||||
func NewAccessToken(userID string) (string, error) {
|
||||
accessExpirationTime := time.Now().Add(5 * time.Second)
|
||||
accessClaims := &AccessTokenClaims{
|
||||
@ -51,7 +75,7 @@ func ValidateAccessToken(accessTokenString string) (AccessTokenClaims, error) {
|
||||
log.WithFields(log.Fields{
|
||||
"token": accessTokenString,
|
||||
"timeToExpire": time.Unix(accessClaims.ExpiresAt, 0),
|
||||
}).Info("token is valid")
|
||||
}).Debug("token is valid")
|
||||
return *accessClaims, nil
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: label_color.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,6 +1,6 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
@ -38,6 +38,14 @@ type ProjectLabel struct {
|
||||
Name sql.NullString `json:"name"`
|
||||
}
|
||||
|
||||
type ProjectMember struct {
|
||||
ProjectMemberID uuid.UUID `json:"project_member_id"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
AddedAt time.Time `json:"added_at"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
||||
|
||||
type RefreshToken struct {
|
||||
TokenID uuid.UUID `json:"token_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
@ -45,6 +53,11 @@ type RefreshToken struct {
|
||||
ExpiresAt time.Time `json:"expires_at"`
|
||||
}
|
||||
|
||||
type Role struct {
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
TaskID uuid.UUID `json:"task_id"`
|
||||
TaskGroupID uuid.UUID `json:"task_group_id"`
|
||||
@ -101,6 +114,7 @@ type Team struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
OrganizationID uuid.UUID `json:"organization_id"`
|
||||
Owner uuid.UUID `json:"owner"`
|
||||
}
|
||||
|
||||
type TeamMember struct {
|
||||
@ -108,6 +122,7 @@ type TeamMember struct {
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Addeddate time.Time `json:"addeddate"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
||||
|
||||
type UserAccount struct {
|
||||
@ -120,4 +135,5 @@ type UserAccount struct {
|
||||
FullName string `json:"full_name"`
|
||||
Initials string `json:"initials"`
|
||||
ProfileAvatarUrl sql.NullString `json:"profile_avatar_url"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: organization.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
294
api/internal/db/project.sql.go
Normal file
294
api/internal/db/project.sql.go
Normal file
@ -0,0 +1,294 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: project.sql
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createProject = `-- name: CreateProject :one
|
||||
INSERT INTO project(owner, team_id, created_at, name) VALUES ($1, $2, $3, $4) RETURNING project_id, team_id, created_at, name, owner
|
||||
`
|
||||
|
||||
type CreateProjectParams struct {
|
||||
Owner uuid.UUID `json:"owner"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateProject(ctx context.Context, arg CreateProjectParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, createProject,
|
||||
arg.Owner,
|
||||
arg.TeamID,
|
||||
arg.CreatedAt,
|
||||
arg.Name,
|
||||
)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const createProjectMember = `-- name: CreateProjectMember :one
|
||||
INSERT INTO project_member (project_id, user_id, role_code, added_at) VALUES ($1, $2, $3, $4)
|
||||
RETURNING project_member_id, project_id, user_id, added_at, role_code
|
||||
`
|
||||
|
||||
type CreateProjectMemberParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
RoleCode string `json:"role_code"`
|
||||
AddedAt time.Time `json:"added_at"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateProjectMember(ctx context.Context, arg CreateProjectMemberParams) (ProjectMember, error) {
|
||||
row := q.db.QueryRowContext(ctx, createProjectMember,
|
||||
arg.ProjectID,
|
||||
arg.UserID,
|
||||
arg.RoleCode,
|
||||
arg.AddedAt,
|
||||
)
|
||||
var i ProjectMember
|
||||
err := row.Scan(
|
||||
&i.ProjectMemberID,
|
||||
&i.ProjectID,
|
||||
&i.UserID,
|
||||
&i.AddedAt,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteProjectByID = `-- name: DeleteProjectByID :exec
|
||||
DELETE FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteProjectByID(ctx context.Context, projectID uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteProjectByID, projectID)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteProjectMember = `-- name: DeleteProjectMember :exec
|
||||
DELETE FROM project_member WHERE user_id = $1 AND project_id = $2
|
||||
`
|
||||
|
||||
type DeleteProjectMemberParams struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteProjectMember(ctx context.Context, arg DeleteProjectMemberParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteProjectMember, arg.UserID, arg.ProjectID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getAllProjects = `-- name: GetAllProjects :many
|
||||
SELECT project_id, team_id, created_at, name, owner FROM project
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllProjects(ctx context.Context) ([]Project, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getAllProjects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Project
|
||||
for rows.Next() {
|
||||
var i Project
|
||||
if err := rows.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getAllProjectsForTeam = `-- name: GetAllProjectsForTeam :many
|
||||
SELECT project_id, team_id, created_at, name, owner FROM project WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getAllProjectsForTeam, teamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Project
|
||||
for rows.Next() {
|
||||
var i Project
|
||||
if err := rows.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getProjectByID = `-- name: GetProjectByID :one
|
||||
SELECT project_id, team_id, created_at, name, owner FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, getProjectByID, projectID)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getProjectMembersForProjectID = `-- name: GetProjectMembersForProjectID :many
|
||||
SELECT project_member_id, project_id, user_id, added_at, role_code FROM project_member WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getProjectMembersForProjectID, projectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ProjectMember
|
||||
for rows.Next() {
|
||||
var i ProjectMember
|
||||
if err := rows.Scan(
|
||||
&i.ProjectMemberID,
|
||||
&i.ProjectID,
|
||||
&i.UserID,
|
||||
&i.AddedAt,
|
||||
&i.RoleCode,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getRoleForProjectMemberByUserID = `-- name: GetRoleForProjectMemberByUserID :one
|
||||
SELECT code, role.name FROM project_member INNER JOIN role ON role.code = project_member.role_code
|
||||
WHERE user_id = $1 AND project_id = $2
|
||||
`
|
||||
|
||||
type GetRoleForProjectMemberByUserIDParams struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetRoleForProjectMemberByUserID(ctx context.Context, arg GetRoleForProjectMemberByUserIDParams) (Role, error) {
|
||||
row := q.db.QueryRowContext(ctx, getRoleForProjectMemberByUserID, arg.UserID, arg.ProjectID)
|
||||
var i Role
|
||||
err := row.Scan(&i.Code, &i.Name)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const setProjectOwner = `-- name: SetProjectOwner :one
|
||||
UPDATE project SET owner = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, owner
|
||||
`
|
||||
|
||||
type SetProjectOwnerParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
Owner uuid.UUID `json:"owner"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetProjectOwner(ctx context.Context, arg SetProjectOwnerParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, setProjectOwner, arg.ProjectID, arg.Owner)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateProjectMemberRole = `-- name: UpdateProjectMemberRole :one
|
||||
UPDATE project_member SET role_code = $3 WHERE project_id = $1 AND user_id = $2
|
||||
RETURNING project_member_id, project_id, user_id, added_at, role_code
|
||||
`
|
||||
|
||||
type UpdateProjectMemberRoleParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateProjectMemberRole(ctx context.Context, arg UpdateProjectMemberRoleParams) (ProjectMember, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateProjectMemberRole, arg.ProjectID, arg.UserID, arg.RoleCode)
|
||||
var i ProjectMember
|
||||
err := row.Scan(
|
||||
&i.ProjectMemberID,
|
||||
&i.ProjectID,
|
||||
&i.UserID,
|
||||
&i.AddedAt,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateProjectNameByID = `-- name: UpdateProjectNameByID :one
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, owner
|
||||
`
|
||||
|
||||
type UpdateProjectNameByIDParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateProjectNameByID, arg.ProjectID, arg.Name)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: project_label.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,6 +1,6 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -13,6 +13,7 @@ type Querier interface {
|
||||
CreateOrganization(ctx context.Context, arg CreateOrganizationParams) (Organization, error)
|
||||
CreateProject(ctx context.Context, arg CreateProjectParams) (Project, error)
|
||||
CreateProjectLabel(ctx context.Context, arg CreateProjectLabelParams) (ProjectLabel, error)
|
||||
CreateProjectMember(ctx context.Context, arg CreateProjectMemberParams) (ProjectMember, error)
|
||||
CreateRefreshToken(ctx context.Context, arg CreateRefreshTokenParams) (RefreshToken, error)
|
||||
CreateTask(ctx context.Context, arg CreateTaskParams) (Task, error)
|
||||
CreateTaskAssigned(ctx context.Context, arg CreateTaskAssignedParams) (TaskAssigned, error)
|
||||
@ -26,6 +27,7 @@ type Querier interface {
|
||||
DeleteExpiredTokens(ctx context.Context) error
|
||||
DeleteProjectByID(ctx context.Context, projectID uuid.UUID) error
|
||||
DeleteProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) error
|
||||
DeleteProjectMember(ctx context.Context, arg DeleteProjectMemberParams) error
|
||||
DeleteRefreshTokenByID(ctx context.Context, tokenID uuid.UUID) error
|
||||
DeleteRefreshTokenByUserID(ctx context.Context, userID uuid.UUID) error
|
||||
DeleteTaskAssignedByID(ctx context.Context, arg DeleteTaskAssignedByIDParams) (TaskAssigned, error)
|
||||
@ -37,7 +39,7 @@ type Querier interface {
|
||||
DeleteTaskLabelForTaskByProjectLabelID(ctx context.Context, arg DeleteTaskLabelForTaskByProjectLabelIDParams) error
|
||||
DeleteTasksByTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
|
||||
DeleteTeamByID(ctx context.Context, teamID uuid.UUID) error
|
||||
DeleteTeamMemberByUserID(ctx context.Context, userID uuid.UUID) error
|
||||
DeleteTeamMember(ctx context.Context, arg DeleteTeamMemberParams) error
|
||||
DeleteUserAccountByID(ctx context.Context, userID uuid.UUID) error
|
||||
GetAllOrganizations(ctx context.Context) ([]Organization, error)
|
||||
GetAllProjects(ctx context.Context) ([]Project, error)
|
||||
@ -50,9 +52,14 @@ type Querier interface {
|
||||
GetLabelColorByID(ctx context.Context, labelColorID uuid.UUID) (LabelColor, error)
|
||||
GetLabelColors(ctx context.Context) ([]LabelColor, error)
|
||||
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
|
||||
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
|
||||
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
|
||||
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
|
||||
GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)
|
||||
GetRefreshTokenByID(ctx context.Context, tokenID uuid.UUID) (RefreshToken, error)
|
||||
GetRoleForProjectMemberByUserID(ctx context.Context, arg GetRoleForProjectMemberByUserIDParams) (Role, error)
|
||||
GetRoleForTeamMember(ctx context.Context, arg GetRoleForTeamMemberParams) (Role, error)
|
||||
GetRoleForUserID(ctx context.Context, userID uuid.UUID) (GetRoleForUserIDRow, error)
|
||||
GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error)
|
||||
GetTaskChecklistByID(ctx context.Context, taskChecklistID uuid.UUID) (TaskChecklist, error)
|
||||
GetTaskChecklistItemByID(ctx context.Context, taskChecklistItemID uuid.UUID) (TaskChecklistItem, error)
|
||||
@ -65,16 +72,20 @@ type Querier interface {
|
||||
GetTaskLabelsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskLabel, error)
|
||||
GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error)
|
||||
GetTeamByID(ctx context.Context, teamID uuid.UUID) (Team, error)
|
||||
GetTeamMemberByID(ctx context.Context, arg GetTeamMemberByIDParams) (TeamMember, error)
|
||||
GetTeamMembersForTeamID(ctx context.Context, teamID uuid.UUID) ([]TeamMember, error)
|
||||
GetTeamsForOrganization(ctx context.Context, organizationID uuid.UUID) ([]Team, error)
|
||||
GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error)
|
||||
GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error)
|
||||
SetProjectOwner(ctx context.Context, arg SetProjectOwnerParams) (Project, error)
|
||||
SetTaskChecklistItemComplete(ctx context.Context, arg SetTaskChecklistItemCompleteParams) (TaskChecklistItem, error)
|
||||
SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams) (Task, error)
|
||||
SetTaskGroupName(ctx context.Context, arg SetTaskGroupNameParams) (TaskGroup, error)
|
||||
SetTeamOwner(ctx context.Context, arg SetTeamOwnerParams) (Team, error)
|
||||
UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
|
||||
UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
|
||||
UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
|
||||
UpdateProjectMemberRole(ctx context.Context, arg UpdateProjectMemberRoleParams) (ProjectMember, error)
|
||||
UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error)
|
||||
UpdateTaskChecklistItemName(ctx context.Context, arg UpdateTaskChecklistItemNameParams) (TaskChecklistItem, error)
|
||||
UpdateTaskChecklistName(ctx context.Context, arg UpdateTaskChecklistNameParams) (TaskChecklist, error)
|
||||
@ -83,6 +94,7 @@ type Querier interface {
|
||||
UpdateTaskGroupLocation(ctx context.Context, arg UpdateTaskGroupLocationParams) (TaskGroup, error)
|
||||
UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocationParams) (Task, error)
|
||||
UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams) (Task, error)
|
||||
UpdateTeamMemberRole(ctx context.Context, arg UpdateTeamMemberRoleParams) (TeamMember, error)
|
||||
UpdateUserAccountProfileAvatarURL(ctx context.Context, arg UpdateUserAccountProfileAvatarURLParams) (UserAccount, error)
|
||||
}
|
||||
|
41
api/internal/db/query/project.sql
Normal file
41
api/internal/db/query/project.sql
Normal file
@ -0,0 +1,41 @@
|
||||
-- name: GetAllProjects :many
|
||||
SELECT * FROM project;
|
||||
|
||||
-- name: GetAllProjectsForTeam :many
|
||||
SELECT * FROM project WHERE team_id = $1;
|
||||
|
||||
-- name: GetProjectByID :one
|
||||
SELECT * FROM project WHERE project_id = $1;
|
||||
|
||||
-- name: CreateProject :one
|
||||
INSERT INTO project(owner, team_id, created_at, name) VALUES ($1, $2, $3, $4) RETURNING *;
|
||||
|
||||
-- name: SetProjectOwner :one
|
||||
UPDATE project SET owner = $2 WHERE project_id = $1 RETURNING *;
|
||||
|
||||
-- name: UpdateProjectNameByID :one
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING *;
|
||||
|
||||
-- name: DeleteProjectByID :exec
|
||||
DELETE FROM project WHERE project_id = $1;
|
||||
|
||||
-- name: GetProjectMembersForProjectID :many
|
||||
SELECT * FROM project_member WHERE project_id = $1;
|
||||
|
||||
-- name: GetRoleForProjectMemberByUserID :one
|
||||
SELECT code, role.name FROM project_member INNER JOIN role ON role.code = project_member.role_code
|
||||
WHERE user_id = $1 AND project_id = $2;
|
||||
|
||||
-- name: CreateProjectMember :one
|
||||
INSERT INTO project_member (project_id, user_id, role_code, added_at) VALUES ($1, $2, $3, $4)
|
||||
RETURNING *;
|
||||
|
||||
-- name: DeleteProjectMember :exec
|
||||
DELETE FROM project_member WHERE user_id = $1 AND project_id = $2;
|
||||
|
||||
-- name: UpdateProjectMemberRole :one
|
||||
UPDATE project_member SET role_code = $3 WHERE project_id = $1 AND user_id = $2
|
||||
RETURNING *;
|
||||
|
||||
|
||||
|
@ -31,3 +31,8 @@ UPDATE task SET due_date = $2 WHERE task_id = $1 RETURNING *;
|
||||
|
||||
-- name: SetTaskComplete :one
|
||||
UPDATE task SET complete = $2 WHERE task_id = $1 RETURNING *;
|
||||
|
||||
-- name: GetProjectIDForTask :one
|
||||
SELECT project_id FROM task
|
||||
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
|
||||
WHERE task_id = $1;
|
@ -5,10 +5,13 @@ SELECT * FROM team;
|
||||
SELECT * FROM team WHERE team_id = $1;
|
||||
|
||||
-- name: CreateTeam :one
|
||||
INSERT INTO team (organization_id, created_at, name) VALUES ($1, $2, $3) RETURNING *;
|
||||
INSERT INTO team (organization_id, created_at, name, owner) VALUES ($1, $2, $3, $4) RETURNING *;
|
||||
|
||||
-- name: DeleteTeamByID :exec
|
||||
DELETE FROM team WHERE team_id = $1;
|
||||
|
||||
-- name: GetTeamsForOrganization :many
|
||||
SELECT * FROM team WHERE organization_id = $1;
|
||||
|
||||
-- name: SetTeamOwner :one
|
||||
UPDATE team SET owner = $2 WHERE team_id = $1 RETURNING *;
|
21
api/internal/db/query/team_member.sql
Normal file
21
api/internal/db/query/team_member.sql
Normal file
@ -0,0 +1,21 @@
|
||||
-- name: CreateTeamMember :one
|
||||
INSERT INTO team_member (team_id, user_id, addedDate, role_code) VALUES ($1, $2, $3, $4)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetTeamMembersForTeamID :many
|
||||
SELECT * FROM team_member WHERE team_id = $1;
|
||||
|
||||
-- name: DeleteTeamMember :exec
|
||||
DELETE FROM team_member WHERE user_id = $1 AND team_id = $2;
|
||||
|
||||
-- name: GetRoleForTeamMember :one
|
||||
SELECT code, role.name FROM team_member
|
||||
INNER JOIN role ON role.code = team_member.role_code
|
||||
WHERE user_id = $1 AND team_id = $2;
|
||||
|
||||
-- name: UpdateTeamMemberRole :one
|
||||
UPDATE team_member SET role_code = $3 WHERE user_id = $2 AND team_id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetTeamMemberByID :one
|
||||
SELECT * FROM team_member WHERE team_id = $1 AND user_id = $2;
|
@ -8,8 +8,8 @@ SELECT * FROM user_account;
|
||||
SELECT * FROM user_account WHERE username = $1;
|
||||
|
||||
-- name: CreateUserAccount :one
|
||||
INSERT INTO user_account(full_name, initials, email, username, created_at, password_hash)
|
||||
VALUES ($1, $2, $3, $4, $5, $6) RETURNING *;
|
||||
INSERT INTO user_account(full_name, initials, email, username, created_at, password_hash, role_code)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING *;
|
||||
|
||||
-- name: UpdateUserAccountProfileAvatarURL :one
|
||||
UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
|
||||
@ -17,3 +17,8 @@ UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
|
||||
|
||||
-- name: DeleteUserAccountByID :exec
|
||||
DELETE FROM user_account WHERE user_id = $1;
|
||||
|
||||
-- name: GetRoleForUserID :one
|
||||
SELECT username, role.code, role.name FROM user_account
|
||||
INNER JOIN role ON role.code = user_account.role_code
|
||||
WHERE user_id = $1;
|
18
api/internal/db/repository.go
Normal file
18
api/internal/db/repository.go
Normal file
@ -0,0 +1,18 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Repository struct {
|
||||
*Queries
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
// NewRepository returns an implementation of the Repository interface.
|
||||
func NewRepository(db *sqlx.DB) *Repository {
|
||||
return &Repository{
|
||||
Queries: New(db.DB),
|
||||
db: db,
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: task.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -101,6 +101,19 @@ func (q *Queries) GetAllTasks(ctx context.Context) ([]Task, error) {
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getProjectIDForTask = `-- name: GetProjectIDForTask :one
|
||||
SELECT project_id FROM task
|
||||
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
|
||||
WHERE task_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error) {
|
||||
row := q.db.QueryRowContext(ctx, getProjectIDForTask, taskID)
|
||||
var project_id uuid.UUID
|
||||
err := row.Scan(&project_id)
|
||||
return project_id, err
|
||||
}
|
||||
|
||||
const getTaskByID = `-- name: GetTaskByID :one
|
||||
SELECT task_id, task_group_id, created_at, name, position, description, due_date, complete FROM task WHERE task_id = $1
|
||||
`
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: task_assigned.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: task_checklist.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: task_group.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: task_label.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: team.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -11,23 +11,30 @@ import (
|
||||
)
|
||||
|
||||
const createTeam = `-- name: CreateTeam :one
|
||||
INSERT INTO team (organization_id, created_at, name) VALUES ($1, $2, $3) RETURNING team_id, created_at, name, organization_id
|
||||
INSERT INTO team (organization_id, created_at, name, owner) VALUES ($1, $2, $3, $4) RETURNING team_id, created_at, name, organization_id, owner
|
||||
`
|
||||
|
||||
type CreateTeamParams struct {
|
||||
OrganizationID uuid.UUID `json:"organization_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
Owner uuid.UUID `json:"owner"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateTeam(ctx context.Context, arg CreateTeamParams) (Team, error) {
|
||||
row := q.db.QueryRowContext(ctx, createTeam, arg.OrganizationID, arg.CreatedAt, arg.Name)
|
||||
row := q.db.QueryRowContext(ctx, createTeam,
|
||||
arg.OrganizationID,
|
||||
arg.CreatedAt,
|
||||
arg.Name,
|
||||
arg.Owner,
|
||||
)
|
||||
var i Team
|
||||
err := row.Scan(
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.OrganizationID,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -42,7 +49,7 @@ func (q *Queries) DeleteTeamByID(ctx context.Context, teamID uuid.UUID) error {
|
||||
}
|
||||
|
||||
const getAllTeams = `-- name: GetAllTeams :many
|
||||
SELECT team_id, created_at, name, organization_id FROM team
|
||||
SELECT team_id, created_at, name, organization_id, owner FROM team
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllTeams(ctx context.Context) ([]Team, error) {
|
||||
@ -59,6 +66,7 @@ func (q *Queries) GetAllTeams(ctx context.Context) ([]Team, error) {
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.OrganizationID,
|
||||
&i.Owner,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -74,7 +82,7 @@ func (q *Queries) GetAllTeams(ctx context.Context) ([]Team, error) {
|
||||
}
|
||||
|
||||
const getTeamByID = `-- name: GetTeamByID :one
|
||||
SELECT team_id, created_at, name, organization_id FROM team WHERE team_id = $1
|
||||
SELECT team_id, created_at, name, organization_id, owner FROM team WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetTeamByID(ctx context.Context, teamID uuid.UUID) (Team, error) {
|
||||
@ -85,12 +93,13 @@ func (q *Queries) GetTeamByID(ctx context.Context, teamID uuid.UUID) (Team, erro
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.OrganizationID,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTeamsForOrganization = `-- name: GetTeamsForOrganization :many
|
||||
SELECT team_id, created_at, name, organization_id FROM team WHERE organization_id = $1
|
||||
SELECT team_id, created_at, name, organization_id, owner FROM team WHERE organization_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetTeamsForOrganization(ctx context.Context, organizationID uuid.UUID) ([]Team, error) {
|
||||
@ -107,6 +116,7 @@ func (q *Queries) GetTeamsForOrganization(ctx context.Context, organizationID uu
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.OrganizationID,
|
||||
&i.Owner,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -120,3 +130,25 @@ func (q *Queries) GetTeamsForOrganization(ctx context.Context, organizationID uu
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const setTeamOwner = `-- name: SetTeamOwner :one
|
||||
UPDATE team SET owner = $2 WHERE team_id = $1 RETURNING team_id, created_at, name, organization_id, owner
|
||||
`
|
||||
|
||||
type SetTeamOwnerParams struct {
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
Owner uuid.UUID `json:"owner"`
|
||||
}
|
||||
|
||||
func (q *Queries) SetTeamOwner(ctx context.Context, arg SetTeamOwnerParams) (Team, error) {
|
||||
row := q.db.QueryRowContext(ctx, setTeamOwner, arg.TeamID, arg.Owner)
|
||||
var i Team
|
||||
err := row.Scan(
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.OrganizationID,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
152
api/internal/db/team_member.sql.go
Normal file
152
api/internal/db/team_member.sql.go
Normal file
@ -0,0 +1,152 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: team_member.sql
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createTeamMember = `-- name: CreateTeamMember :one
|
||||
INSERT INTO team_member (team_id, user_id, addedDate, role_code) VALUES ($1, $2, $3, $4)
|
||||
RETURNING team_member_id, team_id, user_id, addeddate, role_code
|
||||
`
|
||||
|
||||
type CreateTeamMemberParams struct {
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Addeddate time.Time `json:"addeddate"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateTeamMember(ctx context.Context, arg CreateTeamMemberParams) (TeamMember, error) {
|
||||
row := q.db.QueryRowContext(ctx, createTeamMember,
|
||||
arg.TeamID,
|
||||
arg.UserID,
|
||||
arg.Addeddate,
|
||||
arg.RoleCode,
|
||||
)
|
||||
var i TeamMember
|
||||
err := row.Scan(
|
||||
&i.TeamMemberID,
|
||||
&i.TeamID,
|
||||
&i.UserID,
|
||||
&i.Addeddate,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteTeamMember = `-- name: DeleteTeamMember :exec
|
||||
DELETE FROM team_member WHERE user_id = $1 AND team_id = $2
|
||||
`
|
||||
|
||||
type DeleteTeamMemberParams struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteTeamMember(ctx context.Context, arg DeleteTeamMemberParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteTeamMember, arg.UserID, arg.TeamID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getRoleForTeamMember = `-- name: GetRoleForTeamMember :one
|
||||
SELECT code, role.name FROM team_member
|
||||
INNER JOIN role ON role.code = team_member.role_code
|
||||
WHERE user_id = $1 AND team_id = $2
|
||||
`
|
||||
|
||||
type GetRoleForTeamMemberParams struct {
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetRoleForTeamMember(ctx context.Context, arg GetRoleForTeamMemberParams) (Role, error) {
|
||||
row := q.db.QueryRowContext(ctx, getRoleForTeamMember, arg.UserID, arg.TeamID)
|
||||
var i Role
|
||||
err := row.Scan(&i.Code, &i.Name)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTeamMemberByID = `-- name: GetTeamMemberByID :one
|
||||
SELECT team_member_id, team_id, user_id, addeddate, role_code FROM team_member WHERE team_id = $1 AND user_id = $2
|
||||
`
|
||||
|
||||
type GetTeamMemberByIDParams struct {
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetTeamMemberByID(ctx context.Context, arg GetTeamMemberByIDParams) (TeamMember, error) {
|
||||
row := q.db.QueryRowContext(ctx, getTeamMemberByID, arg.TeamID, arg.UserID)
|
||||
var i TeamMember
|
||||
err := row.Scan(
|
||||
&i.TeamMemberID,
|
||||
&i.TeamID,
|
||||
&i.UserID,
|
||||
&i.Addeddate,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getTeamMembersForTeamID = `-- name: GetTeamMembersForTeamID :many
|
||||
SELECT team_member_id, team_id, user_id, addeddate, role_code FROM team_member WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetTeamMembersForTeamID(ctx context.Context, teamID uuid.UUID) ([]TeamMember, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getTeamMembersForTeamID, teamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []TeamMember
|
||||
for rows.Next() {
|
||||
var i TeamMember
|
||||
if err := rows.Scan(
|
||||
&i.TeamMemberID,
|
||||
&i.TeamID,
|
||||
&i.UserID,
|
||||
&i.Addeddate,
|
||||
&i.RoleCode,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const updateTeamMemberRole = `-- name: UpdateTeamMemberRole :one
|
||||
UPDATE team_member SET role_code = $3 WHERE user_id = $2 AND team_id = $1
|
||||
RETURNING team_member_id, team_id, user_id, addeddate, role_code
|
||||
`
|
||||
|
||||
type UpdateTeamMemberRoleParams struct {
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateTeamMemberRole(ctx context.Context, arg UpdateTeamMemberRoleParams) (TeamMember, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateTeamMemberRole, arg.TeamID, arg.UserID, arg.RoleCode)
|
||||
var i TeamMember
|
||||
err := row.Scan(
|
||||
&i.TeamMemberID,
|
||||
&i.TeamID,
|
||||
&i.UserID,
|
||||
&i.Addeddate,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: token.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
@ -1,7 +1,7 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: user_accounts.sql
|
||||
|
||||
package pg
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -12,8 +12,8 @@ import (
|
||||
)
|
||||
|
||||
const createUserAccount = `-- name: CreateUserAccount :one
|
||||
INSERT INTO user_account(full_name, initials, email, username, created_at, password_hash)
|
||||
VALUES ($1, $2, $3, $4, $5, $6) RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url
|
||||
INSERT INTO user_account(full_name, initials, email, username, created_at, password_hash, role_code)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code
|
||||
`
|
||||
|
||||
type CreateUserAccountParams struct {
|
||||
@ -23,6 +23,7 @@ type CreateUserAccountParams struct {
|
||||
Username string `json:"username"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
PasswordHash string `json:"password_hash"`
|
||||
RoleCode string `json:"role_code"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateUserAccount(ctx context.Context, arg CreateUserAccountParams) (UserAccount, error) {
|
||||
@ -33,6 +34,7 @@ func (q *Queries) CreateUserAccount(ctx context.Context, arg CreateUserAccountPa
|
||||
arg.Username,
|
||||
arg.CreatedAt,
|
||||
arg.PasswordHash,
|
||||
arg.RoleCode,
|
||||
)
|
||||
var i UserAccount
|
||||
err := row.Scan(
|
||||
@ -45,6 +47,7 @@ func (q *Queries) CreateUserAccount(ctx context.Context, arg CreateUserAccountPa
|
||||
&i.FullName,
|
||||
&i.Initials,
|
||||
&i.ProfileAvatarUrl,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@ -59,7 +62,7 @@ func (q *Queries) DeleteUserAccountByID(ctx context.Context, userID uuid.UUID) e
|
||||
}
|
||||
|
||||
const getAllUserAccounts = `-- name: GetAllUserAccounts :many
|
||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url FROM user_account
|
||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code FROM user_account
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllUserAccounts(ctx context.Context) ([]UserAccount, error) {
|
||||
@ -81,6 +84,7 @@ func (q *Queries) GetAllUserAccounts(ctx context.Context) ([]UserAccount, error)
|
||||
&i.FullName,
|
||||
&i.Initials,
|
||||
&i.ProfileAvatarUrl,
|
||||
&i.RoleCode,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -95,8 +99,27 @@ func (q *Queries) GetAllUserAccounts(ctx context.Context) ([]UserAccount, error)
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getRoleForUserID = `-- name: GetRoleForUserID :one
|
||||
SELECT username, role.code, role.name FROM user_account
|
||||
INNER JOIN role ON role.code = user_account.role_code
|
||||
WHERE user_id = $1
|
||||
`
|
||||
|
||||
type GetRoleForUserIDRow struct {
|
||||
Username string `json:"username"`
|
||||
Code string `json:"code"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetRoleForUserID(ctx context.Context, userID uuid.UUID) (GetRoleForUserIDRow, error) {
|
||||
row := q.db.QueryRowContext(ctx, getRoleForUserID, userID)
|
||||
var i GetRoleForUserIDRow
|
||||
err := row.Scan(&i.Username, &i.Code, &i.Name)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserAccountByID = `-- name: GetUserAccountByID :one
|
||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url FROM user_account WHERE user_id = $1
|
||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code FROM user_account WHERE user_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error) {
|
||||
@ -112,12 +135,13 @@ func (q *Queries) GetUserAccountByID(ctx context.Context, userID uuid.UUID) (Use
|
||||
&i.FullName,
|
||||
&i.Initials,
|
||||
&i.ProfileAvatarUrl,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getUserAccountByUsername = `-- name: GetUserAccountByUsername :one
|
||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url FROM user_account WHERE username = $1
|
||||
SELECT user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code FROM user_account WHERE username = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error) {
|
||||
@ -133,13 +157,14 @@ func (q *Queries) GetUserAccountByUsername(ctx context.Context, username string)
|
||||
&i.FullName,
|
||||
&i.Initials,
|
||||
&i.ProfileAvatarUrl,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateUserAccountProfileAvatarURL = `-- name: UpdateUserAccountProfileAvatarURL :one
|
||||
UPDATE user_account SET profile_avatar_url = $2 WHERE user_id = $1
|
||||
RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url
|
||||
RETURNING user_id, created_at, email, username, password_hash, profile_bg_color, full_name, initials, profile_avatar_url, role_code
|
||||
`
|
||||
|
||||
type UpdateUserAccountProfileAvatarURLParams struct {
|
||||
@ -160,6 +185,7 @@ func (q *Queries) UpdateUserAccountProfileAvatarURL(ctx context.Context, arg Upd
|
||||
&i.FullName,
|
||||
&i.Initials,
|
||||
&i.ProfileAvatarUrl,
|
||||
&i.RoleCode,
|
||||
)
|
||||
return i, err
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -12,11 +12,11 @@ import (
|
||||
"github.com/99designs/gqlgen/graphql/handler/transport"
|
||||
"github.com/99designs/gqlgen/graphql/playground"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
"github.com/jordanknott/project-citadel/api/internal/db"
|
||||
)
|
||||
|
||||
// NewHandler returns a new graphql endpoint handler.
|
||||
func NewHandler(repo pg.Repository) http.Handler {
|
||||
func NewHandler(repo db.Repository) http.Handler {
|
||||
srv := handler.New(NewExecutableSchema(Config{
|
||||
Resolvers: &Resolver{
|
||||
Repository: repo,
|
@ -3,10 +3,13 @@
|
||||
package graph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
"github.com/jordanknott/project-citadel/api/internal/db"
|
||||
)
|
||||
|
||||
type AddTaskLabelInput struct {
|
||||
@ -24,6 +27,16 @@ type ChecklistBadge struct {
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type CreateProjectMember struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
}
|
||||
|
||||
type CreateProjectMemberPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
Member *Member `json:"member"`
|
||||
}
|
||||
|
||||
type CreateTaskChecklist struct {
|
||||
TaskID uuid.UUID `json:"taskID"`
|
||||
Name string `json:"name"`
|
||||
@ -42,8 +55,8 @@ type CreateTeamMember struct {
|
||||
}
|
||||
|
||||
type CreateTeamMemberPayload struct {
|
||||
Team *pg.Team `json:"team"`
|
||||
TeamMember *ProjectMember `json:"teamMember"`
|
||||
Team *db.Team `json:"team"`
|
||||
TeamMember *Member `json:"teamMember"`
|
||||
}
|
||||
|
||||
type DeleteProject struct {
|
||||
@ -54,9 +67,20 @@ type DeleteProjectLabel struct {
|
||||
ProjectLabelID uuid.UUID `json:"projectLabelID"`
|
||||
}
|
||||
|
||||
type DeleteProjectMember struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
}
|
||||
|
||||
type DeleteProjectMemberPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
Member *Member `json:"member"`
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
}
|
||||
|
||||
type DeleteProjectPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
Project *pg.Project `json:"project"`
|
||||
Project *db.Project `json:"project"`
|
||||
}
|
||||
|
||||
type DeleteTaskChecklist struct {
|
||||
@ -69,12 +93,12 @@ type DeleteTaskChecklistItem struct {
|
||||
|
||||
type DeleteTaskChecklistItemPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
TaskChecklistItem *pg.TaskChecklistItem `json:"taskChecklistItem"`
|
||||
TaskChecklistItem *db.TaskChecklistItem `json:"taskChecklistItem"`
|
||||
}
|
||||
|
||||
type DeleteTaskChecklistPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
TaskChecklist *pg.TaskChecklist `json:"taskChecklist"`
|
||||
TaskChecklist *db.TaskChecklist `json:"taskChecklist"`
|
||||
}
|
||||
|
||||
type DeleteTaskGroupInput struct {
|
||||
@ -84,7 +108,7 @@ type DeleteTaskGroupInput struct {
|
||||
type DeleteTaskGroupPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
AffectedRows int `json:"affectedRows"`
|
||||
TaskGroup *pg.TaskGroup `json:"taskGroup"`
|
||||
TaskGroup *db.TaskGroup `json:"taskGroup"`
|
||||
}
|
||||
|
||||
type DeleteTaskInput struct {
|
||||
@ -99,10 +123,20 @@ type DeleteTeam struct {
|
||||
TeamID uuid.UUID `json:"teamID"`
|
||||
}
|
||||
|
||||
type DeleteTeamMember struct {
|
||||
TeamID uuid.UUID `json:"teamID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
}
|
||||
|
||||
type DeleteTeamMemberPayload struct {
|
||||
TeamID uuid.UUID `json:"teamID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
}
|
||||
|
||||
type DeleteTeamPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
Team *pg.Team `json:"team"`
|
||||
Projects []pg.Project `json:"projects"`
|
||||
Team *db.Team `json:"team"`
|
||||
Projects []db.Project `json:"projects"`
|
||||
}
|
||||
|
||||
type DeleteUserAccount struct {
|
||||
@ -111,7 +145,7 @@ type DeleteUserAccount struct {
|
||||
|
||||
type DeleteUserAccountPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
UserAccount *pg.UserAccount `json:"userAccount"`
|
||||
UserAccount *db.UserAccount `json:"userAccount"`
|
||||
}
|
||||
|
||||
type FindProject struct {
|
||||
@ -134,6 +168,14 @@ type LogoutUser struct {
|
||||
UserID string `json:"userID"`
|
||||
}
|
||||
|
||||
type Member struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Role *db.Role `json:"role"`
|
||||
FullName string `json:"fullName"`
|
||||
Username string `json:"username"`
|
||||
ProfileIcon *ProfileIcon `json:"profileIcon"`
|
||||
}
|
||||
|
||||
type NewProject struct {
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
TeamID uuid.UUID `json:"teamID"`
|
||||
@ -184,6 +226,7 @@ type NewUserAccount struct {
|
||||
FullName string `json:"fullName"`
|
||||
Initials string `json:"initials"`
|
||||
Password string `json:"password"`
|
||||
RoleCode string `json:"roleCode"`
|
||||
}
|
||||
|
||||
type ProfileIcon struct {
|
||||
@ -192,12 +235,6 @@ type ProfileIcon struct {
|
||||
BgColor *string `json:"bgColor"`
|
||||
}
|
||||
|
||||
type ProjectMember struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
ProfileIcon *ProfileIcon `json:"profileIcon"`
|
||||
}
|
||||
|
||||
type ProjectsFilter struct {
|
||||
TeamID *uuid.UUID `json:"teamID"`
|
||||
}
|
||||
@ -206,6 +243,17 @@ type RemoveTaskLabelInput struct {
|
||||
TaskLabelID uuid.UUID `json:"taskLabelID"`
|
||||
}
|
||||
|
||||
type SetProjectOwner struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
OwnerID uuid.UUID `json:"ownerID"`
|
||||
}
|
||||
|
||||
type SetProjectOwnerPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
PrevOwner *Member `json:"prevOwner"`
|
||||
NewOwner *Member `json:"newOwner"`
|
||||
}
|
||||
|
||||
type SetTaskChecklistItemComplete struct {
|
||||
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
|
||||
Complete bool `json:"complete"`
|
||||
@ -216,6 +264,17 @@ type SetTaskComplete struct {
|
||||
Complete bool `json:"complete"`
|
||||
}
|
||||
|
||||
type SetTeamOwner struct {
|
||||
TeamID uuid.UUID `json:"teamID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
}
|
||||
|
||||
type SetTeamOwnerPayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
PrevOwner *Member `json:"prevOwner"`
|
||||
NewOwner *Member `json:"newOwner"`
|
||||
}
|
||||
|
||||
type TaskBadges struct {
|
||||
Checklist *ChecklistBadge `json:"checklist"`
|
||||
}
|
||||
@ -227,7 +286,7 @@ type ToggleTaskLabelInput struct {
|
||||
|
||||
type ToggleTaskLabelPayload struct {
|
||||
Active bool `json:"active"`
|
||||
Task *pg.Task `json:"task"`
|
||||
Task *db.Task `json:"task"`
|
||||
}
|
||||
|
||||
type UnassignTaskInput struct {
|
||||
@ -251,6 +310,17 @@ type UpdateProjectLabelName struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type UpdateProjectMemberRole struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
RoleCode RoleCode `json:"roleCode"`
|
||||
}
|
||||
|
||||
type UpdateProjectMemberRolePayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
Member *Member `json:"member"`
|
||||
}
|
||||
|
||||
type UpdateProjectName struct {
|
||||
ProjectID uuid.UUID `json:"projectID"`
|
||||
Name string `json:"name"`
|
||||
@ -283,10 +353,66 @@ type UpdateTaskGroupName struct {
|
||||
|
||||
type UpdateTaskLocationPayload struct {
|
||||
PreviousTaskGroupID uuid.UUID `json:"previousTaskGroupID"`
|
||||
Task *pg.Task `json:"task"`
|
||||
Task *db.Task `json:"task"`
|
||||
}
|
||||
|
||||
type UpdateTaskName struct {
|
||||
TaskID string `json:"taskID"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type UpdateTeamMemberRole struct {
|
||||
TeamID uuid.UUID `json:"teamID"`
|
||||
UserID uuid.UUID `json:"userID"`
|
||||
RoleCode RoleCode `json:"roleCode"`
|
||||
}
|
||||
|
||||
type UpdateTeamMemberRolePayload struct {
|
||||
Ok bool `json:"ok"`
|
||||
Member *Member `json:"member"`
|
||||
}
|
||||
|
||||
type RoleCode string
|
||||
|
||||
const (
|
||||
RoleCodeOwner RoleCode = "owner"
|
||||
RoleCodeAdmin RoleCode = "admin"
|
||||
RoleCodeMember RoleCode = "member"
|
||||
RoleCodeObserver RoleCode = "observer"
|
||||
)
|
||||
|
||||
var AllRoleCode = []RoleCode{
|
||||
RoleCodeOwner,
|
||||
RoleCodeAdmin,
|
||||
RoleCodeMember,
|
||||
RoleCodeObserver,
|
||||
}
|
||||
|
||||
func (e RoleCode) IsValid() bool {
|
||||
switch e {
|
||||
case RoleCodeOwner, RoleCodeAdmin, RoleCodeMember, RoleCodeObserver:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (e RoleCode) String() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
func (e *RoleCode) UnmarshalGQL(v interface{}) error {
|
||||
str, ok := v.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("enums must be strings")
|
||||
}
|
||||
|
||||
*e = RoleCode(str)
|
||||
if !e.IsValid() {
|
||||
return fmt.Errorf("%s is not a valid RoleCode", str)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e RoleCode) MarshalGQL(w io.Writer) {
|
||||
fmt.Fprint(w, strconv.Quote(e.String()))
|
||||
}
|
@ -1,13 +1,14 @@
|
||||
//go:generate sh ../scripts/genSchema.sh
|
||||
//go:generate go run github.com/99designs/gqlgen
|
||||
package graph
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
"github.com/jordanknott/project-citadel/api/internal/db"
|
||||
)
|
||||
|
||||
type Resolver struct {
|
||||
Repository pg.Repository
|
||||
Repository db.Repository
|
||||
mu sync.Mutex
|
||||
}
|
@ -2,6 +2,13 @@ scalar Time
|
||||
scalar UUID
|
||||
scalar Upload
|
||||
|
||||
enum RoleCode {
|
||||
owner
|
||||
admin
|
||||
member
|
||||
observer
|
||||
}
|
||||
|
||||
type ProjectLabel {
|
||||
id: ID!
|
||||
createdDate: Time!
|
||||
@ -28,9 +35,11 @@ type ProfileIcon {
|
||||
bgColor: String
|
||||
}
|
||||
|
||||
type ProjectMember {
|
||||
type Member {
|
||||
id: ID!
|
||||
role: Role!
|
||||
fullName: String!
|
||||
username: String!
|
||||
profileIcon: ProfileIcon!
|
||||
}
|
||||
|
||||
@ -41,12 +50,18 @@ type RefreshToken {
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
type Role {
|
||||
code: String!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type UserAccount {
|
||||
id: ID!
|
||||
email: String!
|
||||
createdAt: Time!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
role: Role!
|
||||
username: String!
|
||||
profileIcon: ProfileIcon!
|
||||
}
|
||||
@ -55,7 +70,7 @@ type Team {
|
||||
id: ID!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
members: [ProjectMember!]!
|
||||
members: [Member!]!
|
||||
}
|
||||
|
||||
type Project {
|
||||
@ -63,9 +78,9 @@ type Project {
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
team: Team!
|
||||
owner: ProjectMember!
|
||||
owner: Member!
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [ProjectMember!]!
|
||||
members: [Member!]!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
|
||||
@ -96,127 +111,17 @@ type Task {
|
||||
description: String
|
||||
dueDate: Time
|
||||
complete: Boolean!
|
||||
assigned: [ProjectMember!]!
|
||||
assigned: [Member!]!
|
||||
labels: [TaskLabel!]!
|
||||
checklists: [TaskChecklist!]!
|
||||
badges: TaskBadges!
|
||||
}
|
||||
|
||||
input ProjectsFilter {
|
||||
teamID: UUID
|
||||
}
|
||||
|
||||
input FindUser {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input FindProject {
|
||||
projectId: String!
|
||||
}
|
||||
|
||||
input FindTask {
|
||||
taskID: UUID!
|
||||
}
|
||||
|
||||
type Organization {
|
||||
id: ID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input FindTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
users: [UserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!): Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
teams: [Team!]!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: UserAccount!
|
||||
}
|
||||
|
||||
input NewRefreshToken {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input NewUserAccount {
|
||||
username: String!
|
||||
email: String!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
password: String!
|
||||
}
|
||||
|
||||
input NewTeam {
|
||||
name: String!
|
||||
organizationID: UUID!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input NewTaskGroup {
|
||||
projectID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input LogoutUser {
|
||||
userID: String!
|
||||
}
|
||||
input NewTask {
|
||||
taskGroupID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
input NewTaskLocation {
|
||||
taskID: UUID!
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input DeleteTaskInput {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
type DeleteTaskPayload {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
input UpdateTaskName {
|
||||
taskID: String!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input NewTaskGroupLocation {
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input DeleteTaskGroupInput {
|
||||
taskGroupID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTaskGroupPayload {
|
||||
ok: Boolean!
|
||||
affectedRows: Int!
|
||||
taskGroup: TaskGroup!
|
||||
}
|
||||
|
||||
type DeleteTaskChecklistItemPayload {
|
||||
ok: Boolean!
|
||||
taskChecklistItem: TaskChecklistItem!
|
||||
}
|
||||
|
||||
type TaskChecklistItem {
|
||||
id: ID!
|
||||
name: String!
|
||||
@ -233,27 +138,75 @@ type TaskChecklist {
|
||||
items: [TaskChecklistItem!]!
|
||||
}
|
||||
|
||||
input AssignTaskInput {
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
users: [UserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!): Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
teams: [Team!]!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: UserAccount!
|
||||
}
|
||||
|
||||
type Mutation
|
||||
|
||||
input ProjectsFilter {
|
||||
teamID: UUID
|
||||
}
|
||||
|
||||
input FindUser {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input FindProject {
|
||||
projectId: String!
|
||||
}
|
||||
|
||||
input FindTask {
|
||||
taskID: UUID!
|
||||
}
|
||||
|
||||
input FindTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createProject(input: NewProject!): Project!
|
||||
deleteProject(input: DeleteProject!): DeleteProjectPayload!
|
||||
updateProjectName(input: UpdateProjectName): Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UnassignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
input UpdateTaskDescriptionInput {
|
||||
taskID: UUID!
|
||||
description: String!
|
||||
input UpdateProjectName {
|
||||
projectID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input AddTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
input DeleteProject {
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
input RemoveTaskLabelInput {
|
||||
taskLabelID: UUID!
|
||||
type DeleteProjectPayload {
|
||||
ok: Boolean!
|
||||
project: Project!
|
||||
}
|
||||
|
||||
|
||||
extend type Mutation {
|
||||
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
|
||||
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
|
||||
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
|
||||
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
|
||||
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
|
||||
}
|
||||
|
||||
input NewProjectLabel {
|
||||
@ -282,19 +235,88 @@ input UpdateProjectLabelColor {
|
||||
labelColorID: UUID!
|
||||
}
|
||||
|
||||
input ToggleTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
extend type Mutation {
|
||||
createProjectMember(input: CreateProjectMember!): CreateProjectMemberPayload!
|
||||
deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload!
|
||||
updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload!
|
||||
setProjectOwner(input: SetProjectOwner!): SetProjectOwnerPayload!
|
||||
}
|
||||
|
||||
type ToggleTaskLabelPayload {
|
||||
active: Boolean!
|
||||
task: Task!
|
||||
}
|
||||
|
||||
input UpdateProjectName {
|
||||
input CreateProjectMember {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type CreateProjectMemberPayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input DeleteProjectMember {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteProjectMemberPayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
input UpdateProjectMemberRole {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
roleCode: RoleCode!
|
||||
}
|
||||
|
||||
type UpdateProjectMemberRolePayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input SetProjectOwner {
|
||||
projectID: UUID!
|
||||
ownerID: UUID!
|
||||
}
|
||||
type SetProjectOwnerPayload {
|
||||
ok: Boolean!
|
||||
prevOwner: Member!
|
||||
newOwner: Member!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createTask(input: NewTask!): Task!
|
||||
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
|
||||
|
||||
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
|
||||
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
|
||||
updateTaskName(input: UpdateTaskName!): Task!
|
||||
setTaskComplete(input: SetTaskComplete!): Task!
|
||||
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
|
||||
|
||||
assignTask(input: AssignTaskInput): Task!
|
||||
unassignTask(input: UnassignTaskInput): Task!
|
||||
}
|
||||
|
||||
input NewTask {
|
||||
taskGroupID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input AssignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input UnassignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input UpdateTaskDescriptionInput {
|
||||
taskID: UUID!
|
||||
description: String!
|
||||
}
|
||||
|
||||
type UpdateTaskLocationPayload {
|
||||
@ -302,11 +324,6 @@ type UpdateTaskLocationPayload {
|
||||
task: Task!
|
||||
}
|
||||
|
||||
input UpdateTaskGroupName {
|
||||
taskGroupID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateTaskDueDate {
|
||||
taskID: UUID!
|
||||
dueDate: Time
|
||||
@ -317,12 +334,46 @@ input SetTaskComplete {
|
||||
complete: Boolean!
|
||||
}
|
||||
|
||||
input NewTaskLocation {
|
||||
taskID: UUID!
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input DeleteTaskInput {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
type DeleteTaskPayload {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
input UpdateTaskName {
|
||||
taskID: String!
|
||||
name: String!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
|
||||
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
|
||||
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
|
||||
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
|
||||
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
|
||||
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
|
||||
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
|
||||
}
|
||||
|
||||
input CreateTaskChecklist {
|
||||
taskID: UUID!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
type DeleteTaskChecklistItemPayload {
|
||||
ok: Boolean!
|
||||
taskChecklistItem: TaskChecklistItem!
|
||||
}
|
||||
|
||||
input CreateTaskChecklistItem {
|
||||
taskChecklistID: UUID!
|
||||
name: String!
|
||||
@ -333,6 +384,7 @@ input SetTaskChecklistItemComplete {
|
||||
taskChecklistItemID: UUID!
|
||||
complete: Boolean!
|
||||
}
|
||||
|
||||
input DeleteTaskChecklistItem {
|
||||
taskChecklistItemID: UUID!
|
||||
}
|
||||
@ -342,44 +394,6 @@ input UpdateTaskChecklistItemName {
|
||||
name: String!
|
||||
}
|
||||
|
||||
input CreateTeamMember {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type CreateTeamMemberPayload {
|
||||
team: Team!
|
||||
teamMember: ProjectMember!
|
||||
}
|
||||
|
||||
input DeleteProject {
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
type DeleteProjectPayload {
|
||||
ok: Boolean!
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input DeleteTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTeamPayload {
|
||||
ok: Boolean!
|
||||
team: Team!
|
||||
projects: [Project!]!
|
||||
}
|
||||
|
||||
input DeleteUserAccount {
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteUserAccountPayload {
|
||||
ok: Boolean!
|
||||
userAccount: UserAccount!
|
||||
}
|
||||
|
||||
input UpdateTaskChecklistName {
|
||||
taskChecklistID: UUID!
|
||||
name: String!
|
||||
@ -391,54 +405,163 @@ type DeleteTaskChecklistPayload {
|
||||
ok: Boolean!
|
||||
taskChecklist: TaskChecklist!
|
||||
}
|
||||
type Mutation {
|
||||
createRefreshToken(input: NewRefreshToken!): RefreshToken!
|
||||
|
||||
createUserAccount(input: NewUserAccount!): UserAccount!
|
||||
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
|
||||
|
||||
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
|
||||
createTeam(input: NewTeam!): Team!
|
||||
clearProfileAvatar: UserAccount!
|
||||
|
||||
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
|
||||
|
||||
createProject(input: NewProject!): Project!
|
||||
deleteProject(input: DeleteProject!): DeleteProjectPayload!
|
||||
updateProjectName(input: UpdateProjectName): Project!
|
||||
|
||||
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
|
||||
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
|
||||
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
|
||||
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
|
||||
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
|
||||
|
||||
extend type Mutation {
|
||||
createTaskGroup(input: NewTaskGroup!): TaskGroup!
|
||||
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
|
||||
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
|
||||
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
|
||||
}
|
||||
|
||||
input NewTaskGroupLocation {
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input UpdateTaskGroupName {
|
||||
taskGroupID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input DeleteTaskGroupInput {
|
||||
taskGroupID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTaskGroupPayload {
|
||||
ok: Boolean!
|
||||
affectedRows: Int!
|
||||
taskGroup: TaskGroup!
|
||||
}
|
||||
|
||||
input NewTaskGroup {
|
||||
projectID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input AddTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
input RemoveTaskLabelInput {
|
||||
taskLabelID: UUID!
|
||||
}
|
||||
input ToggleTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
type ToggleTaskLabelPayload {
|
||||
active: Boolean!
|
||||
task: Task!
|
||||
}
|
||||
extend type Mutation {
|
||||
addTaskLabel(input: AddTaskLabelInput): Task!
|
||||
removeTaskLabel(input: RemoveTaskLabelInput): Task!
|
||||
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
|
||||
|
||||
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
|
||||
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
|
||||
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
|
||||
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
|
||||
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
|
||||
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
|
||||
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
|
||||
|
||||
createTask(input: NewTask!): Task!
|
||||
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
|
||||
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
|
||||
updateTaskName(input: UpdateTaskName!): Task!
|
||||
setTaskComplete(input: SetTaskComplete!): Task!
|
||||
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
|
||||
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
|
||||
assignTask(input: AssignTaskInput): Task!
|
||||
unassignTask(input: UnassignTaskInput): Task!
|
||||
|
||||
logoutUser(input: LogoutUser!): Boolean!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
|
||||
createTeam(input: NewTeam!): Team!
|
||||
}
|
||||
|
||||
input NewTeam {
|
||||
name: String!
|
||||
organizationID: UUID!
|
||||
}
|
||||
|
||||
input DeleteTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTeamPayload {
|
||||
ok: Boolean!
|
||||
team: Team!
|
||||
projects: [Project!]!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
setTeamOwner(input: SetTeamOwner!): SetTeamOwnerPayload!
|
||||
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
|
||||
updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload!
|
||||
deleteTeamMember(input: DeleteTeamMember!): DeleteTeamMemberPayload!
|
||||
}
|
||||
|
||||
input DeleteTeamMember {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTeamMemberPayload {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input CreateTeamMember {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type CreateTeamMemberPayload {
|
||||
team: Team!
|
||||
teamMember: Member!
|
||||
}
|
||||
|
||||
input UpdateTeamMemberRole {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
roleCode: RoleCode!
|
||||
}
|
||||
|
||||
type UpdateTeamMemberRolePayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input SetTeamOwner {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type SetTeamOwnerPayload {
|
||||
ok: Boolean!
|
||||
prevOwner: Member!
|
||||
newOwner: Member!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createRefreshToken(input: NewRefreshToken!): RefreshToken!
|
||||
createUserAccount(input: NewUserAccount!): UserAccount!
|
||||
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
|
||||
logoutUser(input: LogoutUser!): Boolean!
|
||||
clearProfileAvatar: UserAccount!
|
||||
}
|
||||
|
||||
input NewRefreshToken {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input NewUserAccount {
|
||||
username: String!
|
||||
email: String!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
password: String!
|
||||
roleCode: String!
|
||||
}
|
||||
|
||||
input LogoutUser {
|
||||
userID: String!
|
||||
}
|
||||
|
||||
input DeleteUserAccount {
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteUserAccountPayload {
|
||||
ok: Boolean!
|
||||
userAccount: UserAccount!
|
||||
}
|
||||
|
560
api/internal/graph/schema.graphqls.bak
Normal file
560
api/internal/graph/schema.graphqls.bak
Normal file
@ -0,0 +1,560 @@
|
||||
scalar Time
|
||||
scalar UUID
|
||||
scalar Upload
|
||||
|
||||
enum RoleCode {
|
||||
owner
|
||||
admin
|
||||
member
|
||||
observer
|
||||
}
|
||||
|
||||
type ProjectLabel {
|
||||
id: ID!
|
||||
createdDate: Time!
|
||||
labelColor: LabelColor!
|
||||
name: String
|
||||
}
|
||||
|
||||
type LabelColor {
|
||||
id: ID!
|
||||
name: String!
|
||||
position: Float!
|
||||
colorHex: String!
|
||||
}
|
||||
|
||||
type TaskLabel {
|
||||
id: ID!
|
||||
projectLabel: ProjectLabel!
|
||||
assignedDate: Time!
|
||||
}
|
||||
|
||||
type ProfileIcon {
|
||||
url: String
|
||||
initials: String
|
||||
bgColor: String
|
||||
}
|
||||
|
||||
type Member {
|
||||
id: ID!
|
||||
role: Role!
|
||||
fullName: String!
|
||||
username: String!
|
||||
profileIcon: ProfileIcon!
|
||||
}
|
||||
|
||||
type RefreshToken {
|
||||
id: ID!
|
||||
userId: UUID!
|
||||
expiresAt: Time!
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
type Role {
|
||||
code: String!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type UserAccount {
|
||||
id: ID!
|
||||
email: String!
|
||||
createdAt: Time!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
role: Role!
|
||||
username: String!
|
||||
profileIcon: ProfileIcon!
|
||||
}
|
||||
|
||||
type Team {
|
||||
id: ID!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
members: [Member!]!
|
||||
}
|
||||
|
||||
type Project {
|
||||
id: ID!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
team: Team!
|
||||
owner: Member!
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
|
||||
type TaskGroup {
|
||||
id: ID!
|
||||
projectID: String!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
position: Float!
|
||||
tasks: [Task!]!
|
||||
}
|
||||
|
||||
type ChecklistBadge {
|
||||
complete: Int!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type TaskBadges {
|
||||
checklist: ChecklistBadge
|
||||
}
|
||||
|
||||
type Task {
|
||||
id: ID!
|
||||
taskGroup: TaskGroup!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
position: Float!
|
||||
description: String
|
||||
dueDate: Time
|
||||
complete: Boolean!
|
||||
assigned: [Member!]!
|
||||
labels: [TaskLabel!]!
|
||||
checklists: [TaskChecklist!]!
|
||||
badges: TaskBadges!
|
||||
}
|
||||
|
||||
input ProjectsFilter {
|
||||
teamID: UUID
|
||||
}
|
||||
|
||||
input FindUser {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input FindProject {
|
||||
projectId: String!
|
||||
}
|
||||
|
||||
input FindTask {
|
||||
taskID: UUID!
|
||||
}
|
||||
|
||||
type Organization {
|
||||
id: ID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
|
||||
input ProjectsFilter {
|
||||
teamID: UUID
|
||||
}
|
||||
|
||||
input FindUser {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input FindProject {
|
||||
projectId: String!
|
||||
}
|
||||
|
||||
input FindTask {
|
||||
taskID: UUID!
|
||||
}
|
||||
|
||||
type Organization {
|
||||
id: ID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input FindTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
users: [UserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!): Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
teams: [Team!]!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: UserAccount!
|
||||
}
|
||||
|
||||
type Mutation {}
|
||||
|
||||
extend type Mutation {
|
||||
createTask(input: NewTask!): Task!
|
||||
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
|
||||
|
||||
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
|
||||
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
|
||||
updateTaskName(input: UpdateTaskName!): Task!
|
||||
setTaskComplete(input: SetTaskComplete!): Task!
|
||||
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
|
||||
|
||||
assignTask(input: AssignTaskInput): Task!
|
||||
unassignTask(input: UnassignTaskInput): Task!
|
||||
}
|
||||
|
||||
input NewRefreshToken {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input NewUserAccount {
|
||||
username: String!
|
||||
email: String!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
password: String!
|
||||
roleCode: String!
|
||||
}
|
||||
|
||||
input NewTeam {
|
||||
name: String!
|
||||
organizationID: UUID!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input NewTaskGroup {
|
||||
projectID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input LogoutUser {
|
||||
userID: String!
|
||||
}
|
||||
input NewTask {
|
||||
taskGroupID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
input NewTaskLocation {
|
||||
taskID: UUID!
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input DeleteTaskInput {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
type DeleteTaskPayload {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
input UpdateTaskName {
|
||||
taskID: String!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input NewTaskGroupLocation {
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input DeleteTaskGroupInput {
|
||||
taskGroupID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTaskGroupPayload {
|
||||
ok: Boolean!
|
||||
affectedRows: Int!
|
||||
taskGroup: TaskGroup!
|
||||
}
|
||||
|
||||
type DeleteTaskChecklistItemPayload {
|
||||
ok: Boolean!
|
||||
taskChecklistItem: TaskChecklistItem!
|
||||
}
|
||||
|
||||
type TaskChecklistItem {
|
||||
id: ID!
|
||||
name: String!
|
||||
taskChecklistID: UUID!
|
||||
complete: Boolean!
|
||||
position: Float!
|
||||
dueDate: Time!
|
||||
}
|
||||
|
||||
type TaskChecklist {
|
||||
id: ID!
|
||||
name: String!
|
||||
position: Float!
|
||||
items: [TaskChecklistItem!]!
|
||||
}
|
||||
|
||||
input AssignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input UnassignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
input UpdateTaskDescriptionInput {
|
||||
taskID: UUID!
|
||||
description: String!
|
||||
}
|
||||
|
||||
input AddTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
input RemoveTaskLabelInput {
|
||||
taskLabelID: UUID!
|
||||
}
|
||||
|
||||
input NewProjectLabel {
|
||||
projectID: UUID!
|
||||
labelColorID: UUID!
|
||||
name: String
|
||||
}
|
||||
|
||||
input DeleteProjectLabel {
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
input UpdateProjectLabelName {
|
||||
projectLabelID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateProjectLabel {
|
||||
projectLabelID: UUID!
|
||||
labelColorID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateProjectLabelColor {
|
||||
projectLabelID: UUID!
|
||||
labelColorID: UUID!
|
||||
}
|
||||
|
||||
input ToggleTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
type ToggleTaskLabelPayload {
|
||||
active: Boolean!
|
||||
task: Task!
|
||||
}
|
||||
|
||||
input UpdateProjectName {
|
||||
projectID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type UpdateTaskLocationPayload {
|
||||
previousTaskGroupID: UUID!
|
||||
task: Task!
|
||||
}
|
||||
|
||||
input UpdateTaskGroupName {
|
||||
taskGroupID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateTaskDueDate {
|
||||
taskID: UUID!
|
||||
dueDate: Time
|
||||
}
|
||||
|
||||
input SetTaskComplete {
|
||||
taskID: UUID!
|
||||
complete: Boolean!
|
||||
}
|
||||
|
||||
input CreateTaskChecklist {
|
||||
taskID: UUID!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input CreateTaskChecklistItem {
|
||||
taskChecklistID: UUID!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input SetTaskChecklistItemComplete {
|
||||
taskChecklistItemID: UUID!
|
||||
complete: Boolean!
|
||||
}
|
||||
input DeleteTaskChecklistItem {
|
||||
taskChecklistItemID: UUID!
|
||||
}
|
||||
|
||||
input UpdateTaskChecklistItemName {
|
||||
taskChecklistItemID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input CreateTeamMember {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type CreateTeamMemberPayload {
|
||||
team: Team!
|
||||
teamMember: Member!
|
||||
}
|
||||
|
||||
input DeleteProject {
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
type DeleteProjectPayload {
|
||||
ok: Boolean!
|
||||
project: Project!
|
||||
}
|
||||
|
||||
input DeleteTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTeamPayload {
|
||||
ok: Boolean!
|
||||
team: Team!
|
||||
projects: [Project!]!
|
||||
}
|
||||
|
||||
input DeleteUserAccount {
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteUserAccountPayload {
|
||||
ok: Boolean!
|
||||
userAccount: UserAccount!
|
||||
}
|
||||
|
||||
input UpdateTaskChecklistName {
|
||||
taskChecklistID: UUID!
|
||||
name: String!
|
||||
}
|
||||
input DeleteTaskChecklist {
|
||||
taskChecklistID: UUID!
|
||||
}
|
||||
type DeleteTaskChecklistPayload {
|
||||
ok: Boolean!
|
||||
taskChecklist: TaskChecklist!
|
||||
}
|
||||
|
||||
input CreateProjectMember {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type CreateProjectMemberPayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input DeleteProjectMember {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteProjectMemberPayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
input UpdateProjectMemberRole {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
roleCode: RoleCode!
|
||||
}
|
||||
|
||||
type UpdateProjectMemberRolePayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input SetProjectOwner {
|
||||
projectID: UUID!
|
||||
ownerID: UUID!
|
||||
}
|
||||
type SetProjectOwnerPayload {
|
||||
ok: Boolean!
|
||||
prevOwner: Member!
|
||||
newOwner: Member!
|
||||
}
|
||||
|
||||
input UpdateTeamMemberRole {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
roleCode: RoleCode!
|
||||
}
|
||||
|
||||
type UpdateTeamMemberRolePayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input SetTeamOwner {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type SetTeamOwnerPayload {
|
||||
ok: Boolean!
|
||||
prevOwner: Member!
|
||||
newOwner: Member!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createRefreshToken(input: NewRefreshToken!): RefreshToken!
|
||||
|
||||
createUserAccount(input: NewUserAccount!): UserAccount!
|
||||
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
|
||||
|
||||
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
|
||||
createTeam(input: NewTeam!): Team!
|
||||
clearProfileAvatar: UserAccount!
|
||||
|
||||
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
|
||||
updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload!
|
||||
setTeamOwner(input: SetTeamOwner!): SetTeamOwnerPayload!
|
||||
|
||||
createProject(input: NewProject!): Project!
|
||||
deleteProject(input: DeleteProject!): DeleteProjectPayload!
|
||||
updateProjectName(input: UpdateProjectName): Project!
|
||||
createProjectMember(input: CreateProjectMember!): CreateProjectMemberPayload!
|
||||
deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload!
|
||||
updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload!
|
||||
setProjectOwner(input: SetProjectOwner!): SetProjectOwnerPayload!
|
||||
|
||||
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
|
||||
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
|
||||
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
|
||||
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
|
||||
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
|
||||
|
||||
createTaskGroup(input: NewTaskGroup!): TaskGroup!
|
||||
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
|
||||
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
|
||||
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
|
||||
|
||||
addTaskLabel(input: AddTaskLabelInput): Task!
|
||||
removeTaskLabel(input: RemoveTaskLabelInput): Task!
|
||||
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
|
||||
|
||||
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
|
||||
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
|
||||
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
|
||||
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
|
||||
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
|
||||
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
|
||||
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
|
||||
|
||||
logoutUser(input: LogoutUser!): Boolean!
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
139
api/internal/graph/schema/_models.gql
Normal file
139
api/internal/graph/schema/_models.gql
Normal file
@ -0,0 +1,139 @@
|
||||
scalar Time
|
||||
scalar UUID
|
||||
scalar Upload
|
||||
|
||||
enum RoleCode {
|
||||
owner
|
||||
admin
|
||||
member
|
||||
observer
|
||||
}
|
||||
|
||||
type ProjectLabel {
|
||||
id: ID!
|
||||
createdDate: Time!
|
||||
labelColor: LabelColor!
|
||||
name: String
|
||||
}
|
||||
|
||||
type LabelColor {
|
||||
id: ID!
|
||||
name: String!
|
||||
position: Float!
|
||||
colorHex: String!
|
||||
}
|
||||
|
||||
type TaskLabel {
|
||||
id: ID!
|
||||
projectLabel: ProjectLabel!
|
||||
assignedDate: Time!
|
||||
}
|
||||
|
||||
type ProfileIcon {
|
||||
url: String
|
||||
initials: String
|
||||
bgColor: String
|
||||
}
|
||||
|
||||
type Member {
|
||||
id: ID!
|
||||
role: Role!
|
||||
fullName: String!
|
||||
username: String!
|
||||
profileIcon: ProfileIcon!
|
||||
}
|
||||
|
||||
type RefreshToken {
|
||||
id: ID!
|
||||
userId: UUID!
|
||||
expiresAt: Time!
|
||||
createdAt: Time!
|
||||
}
|
||||
|
||||
type Role {
|
||||
code: String!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type UserAccount {
|
||||
id: ID!
|
||||
email: String!
|
||||
createdAt: Time!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
role: Role!
|
||||
username: String!
|
||||
profileIcon: ProfileIcon!
|
||||
}
|
||||
|
||||
type Team {
|
||||
id: ID!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
members: [Member!]!
|
||||
}
|
||||
|
||||
type Project {
|
||||
id: ID!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
team: Team!
|
||||
owner: Member!
|
||||
taskGroups: [TaskGroup!]!
|
||||
members: [Member!]!
|
||||
labels: [ProjectLabel!]!
|
||||
}
|
||||
|
||||
type TaskGroup {
|
||||
id: ID!
|
||||
projectID: String!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
position: Float!
|
||||
tasks: [Task!]!
|
||||
}
|
||||
|
||||
type ChecklistBadge {
|
||||
complete: Int!
|
||||
total: Int!
|
||||
}
|
||||
|
||||
type TaskBadges {
|
||||
checklist: ChecklistBadge
|
||||
}
|
||||
|
||||
type Task {
|
||||
id: ID!
|
||||
taskGroup: TaskGroup!
|
||||
createdAt: Time!
|
||||
name: String!
|
||||
position: Float!
|
||||
description: String
|
||||
dueDate: Time
|
||||
complete: Boolean!
|
||||
assigned: [Member!]!
|
||||
labels: [TaskLabel!]!
|
||||
checklists: [TaskChecklist!]!
|
||||
badges: TaskBadges!
|
||||
}
|
||||
|
||||
type Organization {
|
||||
id: ID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
type TaskChecklistItem {
|
||||
id: ID!
|
||||
name: String!
|
||||
taskChecklistID: UUID!
|
||||
complete: Boolean!
|
||||
position: Float!
|
||||
dueDate: Time!
|
||||
}
|
||||
|
||||
type TaskChecklist {
|
||||
id: ID!
|
||||
name: String!
|
||||
position: Float!
|
||||
items: [TaskChecklistItem!]!
|
||||
}
|
35
api/internal/graph/schema/_root.gql
Normal file
35
api/internal/graph/schema/_root.gql
Normal file
@ -0,0 +1,35 @@
|
||||
type Query {
|
||||
organizations: [Organization!]!
|
||||
users: [UserAccount!]!
|
||||
findUser(input: FindUser!): UserAccount!
|
||||
findProject(input: FindProject!): Project!
|
||||
findTask(input: FindTask!): Task!
|
||||
projects(input: ProjectsFilter): [Project!]!
|
||||
findTeam(input: FindTeam!): Team!
|
||||
teams: [Team!]!
|
||||
labelColors: [LabelColor!]!
|
||||
taskGroups: [TaskGroup!]!
|
||||
me: UserAccount!
|
||||
}
|
||||
|
||||
type Mutation
|
||||
|
||||
input ProjectsFilter {
|
||||
teamID: UUID
|
||||
}
|
||||
|
||||
input FindUser {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input FindProject {
|
||||
projectId: String!
|
||||
}
|
||||
|
||||
input FindTask {
|
||||
taskID: UUID!
|
||||
}
|
||||
|
||||
input FindTeam {
|
||||
teamID: UUID!
|
||||
}
|
26
api/internal/graph/schema/project.gql
Normal file
26
api/internal/graph/schema/project.gql
Normal file
@ -0,0 +1,26 @@
|
||||
extend type Mutation {
|
||||
createProject(input: NewProject!): Project!
|
||||
deleteProject(input: DeleteProject!): DeleteProjectPayload!
|
||||
updateProjectName(input: UpdateProjectName): Project!
|
||||
}
|
||||
|
||||
input NewProject {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateProjectName {
|
||||
projectID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input DeleteProject {
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
type DeleteProjectPayload {
|
||||
ok: Boolean!
|
||||
project: Project!
|
||||
}
|
||||
|
33
api/internal/graph/schema/project_label.gql
Normal file
33
api/internal/graph/schema/project_label.gql
Normal file
@ -0,0 +1,33 @@
|
||||
extend type Mutation {
|
||||
createProjectLabel(input: NewProjectLabel!): ProjectLabel!
|
||||
deleteProjectLabel(input: DeleteProjectLabel!): ProjectLabel!
|
||||
updateProjectLabel(input: UpdateProjectLabel!): ProjectLabel!
|
||||
updateProjectLabelName(input: UpdateProjectLabelName!): ProjectLabel!
|
||||
updateProjectLabelColor(input: UpdateProjectLabelColor!): ProjectLabel!
|
||||
}
|
||||
|
||||
input NewProjectLabel {
|
||||
projectID: UUID!
|
||||
labelColorID: UUID!
|
||||
name: String
|
||||
}
|
||||
|
||||
input DeleteProjectLabel {
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
input UpdateProjectLabelName {
|
||||
projectLabelID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateProjectLabel {
|
||||
projectLabelID: UUID!
|
||||
labelColorID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateProjectLabelColor {
|
||||
projectLabelID: UUID!
|
||||
labelColorID: UUID!
|
||||
}
|
48
api/internal/graph/schema/project_member.gql
Normal file
48
api/internal/graph/schema/project_member.gql
Normal file
@ -0,0 +1,48 @@
|
||||
extend type Mutation {
|
||||
createProjectMember(input: CreateProjectMember!): CreateProjectMemberPayload!
|
||||
deleteProjectMember(input: DeleteProjectMember!): DeleteProjectMemberPayload!
|
||||
updateProjectMemberRole(input: UpdateProjectMemberRole!): UpdateProjectMemberRolePayload!
|
||||
setProjectOwner(input: SetProjectOwner!): SetProjectOwnerPayload!
|
||||
}
|
||||
|
||||
input CreateProjectMember {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type CreateProjectMemberPayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input DeleteProjectMember {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteProjectMemberPayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
projectID: UUID!
|
||||
}
|
||||
|
||||
input UpdateProjectMemberRole {
|
||||
projectID: UUID!
|
||||
userID: UUID!
|
||||
roleCode: RoleCode!
|
||||
}
|
||||
|
||||
type UpdateProjectMemberRolePayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input SetProjectOwner {
|
||||
projectID: UUID!
|
||||
ownerID: UUID!
|
||||
}
|
||||
type SetProjectOwnerPayload {
|
||||
ok: Boolean!
|
||||
prevOwner: Member!
|
||||
newOwner: Member!
|
||||
}
|
68
api/internal/graph/schema/task.gql
Normal file
68
api/internal/graph/schema/task.gql
Normal file
@ -0,0 +1,68 @@
|
||||
extend type Mutation {
|
||||
createTask(input: NewTask!): Task!
|
||||
deleteTask(input: DeleteTaskInput!): DeleteTaskPayload!
|
||||
|
||||
updateTaskDescription(input: UpdateTaskDescriptionInput!): Task!
|
||||
updateTaskLocation(input: NewTaskLocation!): UpdateTaskLocationPayload!
|
||||
updateTaskName(input: UpdateTaskName!): Task!
|
||||
setTaskComplete(input: SetTaskComplete!): Task!
|
||||
updateTaskDueDate(input: UpdateTaskDueDate!): Task!
|
||||
|
||||
assignTask(input: AssignTaskInput): Task!
|
||||
unassignTask(input: UnassignTaskInput): Task!
|
||||
}
|
||||
|
||||
input NewTask {
|
||||
taskGroupID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input AssignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input UnassignTaskInput {
|
||||
taskID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input UpdateTaskDescriptionInput {
|
||||
taskID: UUID!
|
||||
description: String!
|
||||
}
|
||||
|
||||
type UpdateTaskLocationPayload {
|
||||
previousTaskGroupID: UUID!
|
||||
task: Task!
|
||||
}
|
||||
|
||||
input UpdateTaskDueDate {
|
||||
taskID: UUID!
|
||||
dueDate: Time
|
||||
}
|
||||
|
||||
input SetTaskComplete {
|
||||
taskID: UUID!
|
||||
complete: Boolean!
|
||||
}
|
||||
|
||||
input NewTaskLocation {
|
||||
taskID: UUID!
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input DeleteTaskInput {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
type DeleteTaskPayload {
|
||||
taskID: String!
|
||||
}
|
||||
|
||||
input UpdateTaskName {
|
||||
taskID: String!
|
||||
name: String!
|
||||
}
|
52
api/internal/graph/schema/task_checklist.gql
Normal file
52
api/internal/graph/schema/task_checklist.gql
Normal file
@ -0,0 +1,52 @@
|
||||
extend type Mutation {
|
||||
createTaskChecklist(input: CreateTaskChecklist!): TaskChecklist!
|
||||
deleteTaskChecklist(input: DeleteTaskChecklist!): DeleteTaskChecklistPayload!
|
||||
updateTaskChecklistName(input: UpdateTaskChecklistName!): TaskChecklist!
|
||||
createTaskChecklistItem(input: CreateTaskChecklistItem!): TaskChecklistItem!
|
||||
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!): TaskChecklistItem!
|
||||
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!): TaskChecklistItem!
|
||||
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!): DeleteTaskChecklistItemPayload!
|
||||
}
|
||||
|
||||
input CreateTaskChecklist {
|
||||
taskID: UUID!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
type DeleteTaskChecklistItemPayload {
|
||||
ok: Boolean!
|
||||
taskChecklistItem: TaskChecklistItem!
|
||||
}
|
||||
|
||||
input CreateTaskChecklistItem {
|
||||
taskChecklistID: UUID!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input SetTaskChecklistItemComplete {
|
||||
taskChecklistItemID: UUID!
|
||||
complete: Boolean!
|
||||
}
|
||||
|
||||
input DeleteTaskChecklistItem {
|
||||
taskChecklistItemID: UUID!
|
||||
}
|
||||
|
||||
input UpdateTaskChecklistItemName {
|
||||
taskChecklistItemID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input UpdateTaskChecklistName {
|
||||
taskChecklistID: UUID!
|
||||
name: String!
|
||||
}
|
||||
input DeleteTaskChecklist {
|
||||
taskChecklistID: UUID!
|
||||
}
|
||||
type DeleteTaskChecklistPayload {
|
||||
ok: Boolean!
|
||||
taskChecklist: TaskChecklist!
|
||||
}
|
32
api/internal/graph/schema/task_group.gql
Normal file
32
api/internal/graph/schema/task_group.gql
Normal file
@ -0,0 +1,32 @@
|
||||
extend type Mutation {
|
||||
createTaskGroup(input: NewTaskGroup!): TaskGroup!
|
||||
updateTaskGroupLocation(input: NewTaskGroupLocation!): TaskGroup!
|
||||
updateTaskGroupName(input: UpdateTaskGroupName!): TaskGroup!
|
||||
deleteTaskGroup(input: DeleteTaskGroupInput!): DeleteTaskGroupPayload!
|
||||
}
|
||||
|
||||
input NewTaskGroupLocation {
|
||||
taskGroupID: UUID!
|
||||
position: Float!
|
||||
}
|
||||
|
||||
input UpdateTaskGroupName {
|
||||
taskGroupID: UUID!
|
||||
name: String!
|
||||
}
|
||||
|
||||
input DeleteTaskGroupInput {
|
||||
taskGroupID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTaskGroupPayload {
|
||||
ok: Boolean!
|
||||
affectedRows: Int!
|
||||
taskGroup: TaskGroup!
|
||||
}
|
||||
|
||||
input NewTaskGroup {
|
||||
projectID: String!
|
||||
name: String!
|
||||
position: Float!
|
||||
}
|
22
api/internal/graph/schema/task_label.gql
Normal file
22
api/internal/graph/schema/task_label.gql
Normal file
@ -0,0 +1,22 @@
|
||||
input AddTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
input RemoveTaskLabelInput {
|
||||
taskLabelID: UUID!
|
||||
}
|
||||
input ToggleTaskLabelInput {
|
||||
taskID: UUID!
|
||||
projectLabelID: UUID!
|
||||
}
|
||||
|
||||
type ToggleTaskLabelPayload {
|
||||
active: Boolean!
|
||||
task: Task!
|
||||
}
|
||||
extend type Mutation {
|
||||
addTaskLabel(input: AddTaskLabelInput): Task!
|
||||
removeTaskLabel(input: RemoveTaskLabelInput): Task!
|
||||
toggleTaskLabel(input: ToggleTaskLabelInput!): ToggleTaskLabelPayload!
|
||||
}
|
19
api/internal/graph/schema/team.gql
Normal file
19
api/internal/graph/schema/team.gql
Normal file
@ -0,0 +1,19 @@
|
||||
extend type Mutation {
|
||||
deleteTeam(input: DeleteTeam!): DeleteTeamPayload!
|
||||
createTeam(input: NewTeam!): Team!
|
||||
}
|
||||
|
||||
input NewTeam {
|
||||
name: String!
|
||||
organizationID: UUID!
|
||||
}
|
||||
|
||||
input DeleteTeam {
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTeamPayload {
|
||||
ok: Boolean!
|
||||
team: Team!
|
||||
projects: [Project!]!
|
||||
}
|
48
api/internal/graph/schema/team_member.gql
Normal file
48
api/internal/graph/schema/team_member.gql
Normal file
@ -0,0 +1,48 @@
|
||||
extend type Mutation {
|
||||
setTeamOwner(input: SetTeamOwner!): SetTeamOwnerPayload!
|
||||
createTeamMember(input: CreateTeamMember!): CreateTeamMemberPayload!
|
||||
updateTeamMemberRole(input: UpdateTeamMemberRole!): UpdateTeamMemberRolePayload!
|
||||
deleteTeamMember(input: DeleteTeamMember!): DeleteTeamMemberPayload!
|
||||
}
|
||||
|
||||
input DeleteTeamMember {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteTeamMemberPayload {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
input CreateTeamMember {
|
||||
userID: UUID!
|
||||
teamID: UUID!
|
||||
}
|
||||
|
||||
type CreateTeamMemberPayload {
|
||||
team: Team!
|
||||
teamMember: Member!
|
||||
}
|
||||
|
||||
input UpdateTeamMemberRole {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
roleCode: RoleCode!
|
||||
}
|
||||
|
||||
type UpdateTeamMemberRolePayload {
|
||||
ok: Boolean!
|
||||
member: Member!
|
||||
}
|
||||
|
||||
input SetTeamOwner {
|
||||
teamID: UUID!
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type SetTeamOwnerPayload {
|
||||
ok: Boolean!
|
||||
prevOwner: Member!
|
||||
newOwner: Member!
|
||||
}
|
33
api/internal/graph/schema/user.gql
Normal file
33
api/internal/graph/schema/user.gql
Normal file
@ -0,0 +1,33 @@
|
||||
extend type Mutation {
|
||||
createRefreshToken(input: NewRefreshToken!): RefreshToken!
|
||||
createUserAccount(input: NewUserAccount!): UserAccount!
|
||||
deleteUserAccount(input: DeleteUserAccount!): DeleteUserAccountPayload!
|
||||
logoutUser(input: LogoutUser!): Boolean!
|
||||
clearProfileAvatar: UserAccount!
|
||||
}
|
||||
|
||||
input NewRefreshToken {
|
||||
userId: String!
|
||||
}
|
||||
|
||||
input NewUserAccount {
|
||||
username: String!
|
||||
email: String!
|
||||
fullName: String!
|
||||
initials: String!
|
||||
password: String!
|
||||
roleCode: String!
|
||||
}
|
||||
|
||||
input LogoutUser {
|
||||
userID: String!
|
||||
}
|
||||
|
||||
input DeleteUserAccount {
|
||||
userID: UUID!
|
||||
}
|
||||
|
||||
type DeleteUserAccountPayload {
|
||||
ok: Boolean!
|
||||
userAccount: UserAccount!
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package router
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -57,8 +57,7 @@ func (l *StructuredLoggerEntry) Write(status, bytes int, elapsed time.Duration)
|
||||
"resp_status": status, "resp_bytes_length": bytes,
|
||||
"resp_elapsed_ms": float64(elapsed.Nanoseconds()) / 1000000.0,
|
||||
})
|
||||
|
||||
l.Logger.Infoln("request complete")
|
||||
l.Logger.Debugln("request complete")
|
||||
}
|
||||
|
||||
func (l *StructuredLoggerEntry) Panic(v interface{}, stack []byte) {
|
@ -1,13 +1,15 @@
|
||||
package router
|
||||
package route
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
"github.com/jordanknott/project-citadel/api/internal/auth"
|
||||
"github.com/jordanknott/project-citadel/api/internal/db"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
@ -16,6 +18,38 @@ var jwtKey = []byte("citadel_test_key")
|
||||
|
||||
type authResource struct{}
|
||||
|
||||
type AccessTokenClaims struct {
|
||||
UserID string `json:"userId"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type RefreshTokenClaims struct {
|
||||
UserID string `json:"userId"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type LoginRequestData struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type LoginResponseData struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
}
|
||||
|
||||
type LogoutResponseData struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type RefreshTokenResponseData struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
}
|
||||
|
||||
type AvatarUploadResponseData struct {
|
||||
UserID string `json:"userID"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (h *CitadelHandler) RefreshTokenHandler(w http.ResponseWriter, r *http.Request) {
|
||||
c, err := r.Cookie("refreshToken")
|
||||
if err != nil {
|
||||
@ -35,14 +69,14 @@ func (h *CitadelHandler) RefreshTokenHandler(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
refreshCreatedAt := time.Now().UTC()
|
||||
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), pg.CreateRefreshTokenParams{token.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{token.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||
|
||||
err = h.repo.DeleteRefreshTokenByID(r.Context(), token.TokenID)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
accessTokenString, err := NewAccessToken(token.UserID.String())
|
||||
accessTokenString, err := auth.NewAccessToken(token.UserID.String())
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
@ -106,9 +140,9 @@ func (h *CitadelHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
refreshCreatedAt := time.Now().UTC()
|
||||
refreshExpiresAt := refreshCreatedAt.AddDate(0, 0, 1)
|
||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), pg.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||
refreshTokenString, err := h.repo.CreateRefreshToken(r.Context(), db.CreateRefreshTokenParams{user.UserID, refreshCreatedAt, refreshExpiresAt})
|
||||
|
||||
accessTokenString, err := NewAccessToken(user.UserID.String())
|
||||
accessTokenString, err := auth.NewAccessToken(user.UserID.String())
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
52
api/internal/route/avatar.go
Normal file
52
api/internal/route/avatar.go
Normal file
@ -0,0 +1,52 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/jordanknott/project-citadel/api/internal/db"
|
||||
)
|
||||
|
||||
func (h *CitadelHandler) ProfileImageUpload(w http.ResponseWriter, r *http.Request) {
|
||||
log.Info("preparing to upload file")
|
||||
userID, ok := r.Context().Value("userID").(uuid.UUID)
|
||||
if !ok {
|
||||
log.Error("not a valid uuid")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse our multipart form, 10 << 20 specifies a maximum
|
||||
// upload of 10 MB files.
|
||||
r.ParseMultipartForm(10 << 20)
|
||||
|
||||
file, handler, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
log.WithError(err).Error("issue while uploading file")
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
log.WithFields(log.Fields{"filename": handler.Filename, "size": handler.Size, "header": handler.Header}).Info("file metadata")
|
||||
|
||||
fileBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("while reading file")
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile("uploads/"+handler.Filename, fileBytes, 0644)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("while reading file")
|
||||
return
|
||||
}
|
||||
|
||||
h.repo.UpdateUserAccountProfileAvatarURL(r.Context(), db.UpdateUserAccountProfileAvatarURLParams{UserID: userID, ProfileAvatarUrl: sql.NullString{String: "http://localhost:3333/uploads/" + handler.Filename, Valid: true}})
|
||||
// return that we have successfully uploaded our file!
|
||||
log.Info("file uploaded")
|
||||
json.NewEncoder(w).Encode(AvatarUploadResponseData{URL: "http://localhost:3333/uploads/" + handler.Filename, UserID: userID.String()})
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package router
|
||||
package route
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/project-citadel/api/internal/auth"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -13,17 +14,14 @@ func AuthenticationMiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
bearerTokenRaw := r.Header.Get("Authorization")
|
||||
splitToken := strings.Split(bearerTokenRaw, "Bearer")
|
||||
log.WithFields(log.Fields{
|
||||
"bearerToken": bearerTokenRaw,
|
||||
}).Warning("loading bearer token")
|
||||
if len(splitToken) != 2 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
accessTokenString := strings.TrimSpace(splitToken[1])
|
||||
accessClaims, err := ValidateAccessToken(accessTokenString)
|
||||
accessClaims, err := auth.ValidateAccessToken(accessTokenString)
|
||||
if err != nil {
|
||||
if _, ok := err.(*ErrExpiredToken); ok {
|
||||
if _, ok := err.(*auth.ErrExpiredToken); ok {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{
|
||||
"data": {},
|
66
api/internal/route/route.go
Normal file
66
api/internal/route/route.go
Normal file
@ -0,0 +1,66 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/jmoiron/sqlx"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/jordanknott/project-citadel/api/internal/db"
|
||||
"github.com/jordanknott/project-citadel/api/internal/graph"
|
||||
"github.com/jordanknott/project-citadel/api/internal/logger"
|
||||
)
|
||||
|
||||
type CitadelHandler struct {
|
||||
repo db.Repository
|
||||
}
|
||||
|
||||
func NewRouter(dbConnection *sqlx.DB) (chi.Router, error) {
|
||||
formatter := new(log.TextFormatter)
|
||||
formatter.TimestampFormat = "02-01-2006 15:04:05"
|
||||
formatter.FullTimestamp = true
|
||||
|
||||
routerLogger := log.New()
|
||||
routerLogger.SetLevel(log.InfoLevel)
|
||||
routerLogger.Formatter = formatter
|
||||
r := chi.NewRouter()
|
||||
cors := cors.New(cors.Options{
|
||||
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
|
||||
AllowedOrigins: []string{"*"},
|
||||
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "Cookie"},
|
||||
ExposedHeaders: []string{"Link"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 300, // Maximum value not ignored by any of major browsers
|
||||
})
|
||||
|
||||
r.Use(cors.Handler)
|
||||
r.Use(middleware.RequestID)
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(logger.NewStructuredLogger(routerLogger))
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Timeout(60 * time.Second))
|
||||
|
||||
repository := db.NewRepository(dbConnection)
|
||||
citadelHandler := CitadelHandler{*repository}
|
||||
|
||||
var imgServer = http.FileServer(http.Dir("./uploads/"))
|
||||
r.Group(func(mux chi.Router) {
|
||||
mux.Mount("/auth", authResource{}.Routes(citadelHandler))
|
||||
mux.Handle("/__graphql", graph.NewPlaygroundHandler("/graphql"))
|
||||
mux.Mount("/uploads/", http.StripPrefix("/uploads/", imgServer))
|
||||
|
||||
})
|
||||
r.Group(func(mux chi.Router) {
|
||||
mux.Use(AuthenticationMiddleware)
|
||||
mux.Post("/users/me/avatar", citadelHandler.ProfileImageUpload)
|
||||
mux.Handle("/graphql", graph.NewHandler(*repository))
|
||||
})
|
||||
|
||||
return r, nil
|
||||
}
|
45
api/magefile.go
Normal file
45
api/magefile.go
Normal file
@ -0,0 +1,45 @@
|
||||
//+build mage
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/magefile/mage/sh"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var Aliases = map[string]interface{}{
|
||||
"g": Generate,
|
||||
}
|
||||
|
||||
// Runs go mod download and then installs the binary.
|
||||
func Generate() error {
|
||||
|
||||
files, err := ioutil.ReadDir("graph/schema/")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var schema strings.Builder
|
||||
for _, file := range files {
|
||||
filename := "graph/schema/" + file.Name()
|
||||
fmt.Println(filename)
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
content, err := ioutil.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Fprintln(&schema, string(content))
|
||||
}
|
||||
// return sh.Run("go", "install", "./...")
|
||||
// fmt.Println(schema.String())
|
||||
err = ioutil.WriteFile("graph/schema.graphqls", []byte(schema.String()), os.FileMode(0755))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sh.Run("gqlgen")
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
|
||||
CREATE TABLE refresh_token (
|
||||
token_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id uuid NOT NULL,
|
||||
|
@ -3,3 +3,5 @@ CREATE TABLE organization (
|
||||
created_at timestamptz NOT NULL,
|
||||
name text NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO organization (created_at, name) VALUES (NOW(), 'sys_default_organization');
|
||||
|
6
api/migrations/0037_add-project_member-table.up.sql
Normal file
6
api/migrations/0037_add-project_member-table.up.sql
Normal file
@ -0,0 +1,6 @@
|
||||
CREATE TABLE project_member (
|
||||
project_member_id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
project_id uuid NOT NULL REFERENCES project(project_id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES user_account(user_id) ON DELETE CASCADE,
|
||||
added_at timestamptz NOT NULL
|
||||
);
|
9
api/migrations/0038_add-role-table.up.sql
Normal file
9
api/migrations/0038_add-role-table.up.sql
Normal file
@ -0,0 +1,9 @@
|
||||
CREATE TABLE role (
|
||||
code TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL
|
||||
);
|
||||
|
||||
INSERT INTO role VALUES ('owner', 'Owner');
|
||||
INSERT INTO role VALUES ('admin', 'Admin');
|
||||
INSERT INTO role VALUES ('member', 'Member');
|
||||
INSERT INTO role VALUES ('observer', 'Observer');
|
@ -0,0 +1,2 @@
|
||||
ALTER TABLE user_account ADD COLUMN role_code text
|
||||
NOT NULL REFERENCES role(code) ON DELETE CASCADE DEFAULT 'member';
|
@ -0,0 +1 @@
|
||||
ALTER TABLE project_member ADD UNIQUE (project_id, user_id);
|
@ -0,0 +1,2 @@
|
||||
ALTER TABLE project_member ADD COLUMN role_code TEXT
|
||||
NOT NULL REFERENCES role(code) ON DELETE CASCADE DEFAULT 'member';
|
@ -0,0 +1 @@
|
||||
ALTER TABLE user_account ALTER COLUMN profile_avatar_url SET DEFAULT null;
|
@ -0,0 +1 @@
|
||||
ALTER TABLE team_member ADD COLUMN role_code TEXT NOT NULL REFERENCES role(code) ON DELETE CASCADE;
|
4
api/migrations/0044_add-owner-to-team-table.up.sql
Normal file
4
api/migrations/0044_add-owner-to-team-table.up.sql
Normal file
@ -0,0 +1,4 @@
|
||||
ALTER TABLE team ADD COLUMN owner uuid REFERENCES user_account(user_id) ON DELETE
|
||||
CASCADE;
|
||||
UPDATE team SET owner = (SELECT user_id FROM user_account WHERE role_code = 'admin' LIMIT 1);
|
||||
ALTER TABLE team ALTER COLUMN owner SET NOT NULL;
|
114
api/pg/pg.go
114
api/pg/pg.go
@ -1,114 +0,0 @@
|
||||
package pg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type Repository interface {
|
||||
CreateTeamMember(ctx context.Context, arg CreateTeamMemberParams) (TeamMember, error)
|
||||
DeleteTeamMemberByUserID(ctx context.Context, userID uuid.UUID) error
|
||||
GetTeamMembersForTeamID(ctx context.Context, teamID uuid.UUID) ([]TeamMember, error)
|
||||
|
||||
CreateTeam(ctx context.Context, arg CreateTeamParams) (Team, error)
|
||||
DeleteTeamByID(ctx context.Context, teamID uuid.UUID) error
|
||||
GetTeamByID(ctx context.Context, teamID uuid.UUID) (Team, error)
|
||||
GetAllTeams(ctx context.Context) ([]Team, error)
|
||||
|
||||
DeleteProjectByID(ctx context.Context, projectID uuid.UUID) error
|
||||
DeleteUserAccountByID(ctx context.Context, userID uuid.UUID) error
|
||||
|
||||
GetTaskChecklistByID(ctx context.Context, taskChecklistID uuid.UUID) (TaskChecklist, error)
|
||||
DeleteTaskChecklistByID(ctx context.Context, taskChecklistID uuid.UUID) error
|
||||
UpdateTaskChecklistName(ctx context.Context, arg UpdateTaskChecklistNameParams) (TaskChecklist, error)
|
||||
CreateProject(ctx context.Context, arg CreateProjectParams) (Project, error)
|
||||
GetAllProjects(ctx context.Context) ([]Project, error)
|
||||
GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error)
|
||||
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
|
||||
|
||||
UpdateTaskChecklistItemName(ctx context.Context, arg UpdateTaskChecklistItemNameParams) (TaskChecklistItem, error)
|
||||
GetTaskChecklistItemByID(ctx context.Context, taskChecklistItemID uuid.UUID) (TaskChecklistItem, error)
|
||||
CreateTaskChecklist(ctx context.Context, arg CreateTaskChecklistParams) (TaskChecklist, error)
|
||||
CreateTaskChecklistItem(ctx context.Context, arg CreateTaskChecklistItemParams) (TaskChecklistItem, error)
|
||||
GetTaskChecklistItemsForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) ([]TaskChecklistItem, error)
|
||||
GetTaskChecklistsForTask(ctx context.Context, taskID uuid.UUID) ([]TaskChecklist, error)
|
||||
SetTaskChecklistItemComplete(ctx context.Context, arg SetTaskChecklistItemCompleteParams) (TaskChecklistItem, error)
|
||||
DeleteTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) error
|
||||
|
||||
UpdateUserAccountProfileAvatarURL(ctx context.Context, arg UpdateUserAccountProfileAvatarURLParams) (UserAccount, error)
|
||||
|
||||
CreateUserAccount(ctx context.Context, arg CreateUserAccountParams) (UserAccount, error)
|
||||
GetUserAccountByID(ctx context.Context, userID uuid.UUID) (UserAccount, error)
|
||||
GetUserAccountByUsername(ctx context.Context, username string) (UserAccount, error)
|
||||
GetAllUserAccounts(ctx context.Context) ([]UserAccount, error)
|
||||
|
||||
GetTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) (TaskLabel, error)
|
||||
|
||||
SetTaskComplete(ctx context.Context, arg SetTaskCompleteParams) (Task, error)
|
||||
DeleteTaskLabelForTaskByProjectLabelID(ctx context.Context, arg DeleteTaskLabelForTaskByProjectLabelIDParams) error
|
||||
GetTaskLabelForTaskByProjectLabelID(ctx context.Context, arg GetTaskLabelForTaskByProjectLabelIDParams) (TaskLabel, error)
|
||||
UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error)
|
||||
|
||||
DeleteTaskLabelByID(ctx context.Context, taskLabelID uuid.UUID) error
|
||||
UpdateTaskDueDate(ctx context.Context, arg UpdateTaskDueDateParams) (Task, error)
|
||||
CreateProjectLabel(ctx context.Context, arg CreateProjectLabelParams) (ProjectLabel, error)
|
||||
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
|
||||
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
|
||||
DeleteProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) error
|
||||
UpdateProjectLabelColor(ctx context.Context, arg UpdateProjectLabelColorParams) (ProjectLabel, error)
|
||||
UpdateProjectLabelName(ctx context.Context, arg UpdateProjectLabelNameParams) (ProjectLabel, error)
|
||||
UpdateProjectLabel(ctx context.Context, arg UpdateProjectLabelParams) (ProjectLabel, error)
|
||||
|
||||
GetLabelColors(ctx context.Context) ([]LabelColor, error)
|
||||
CreateLabelColor(ctx context.Context, arg CreateLabelColorParams) (LabelColor, error)
|
||||
|
||||
CreateRefreshToken(ctx context.Context, arg CreateRefreshTokenParams) (RefreshToken, error)
|
||||
GetRefreshTokenByID(ctx context.Context, tokenID uuid.UUID) (RefreshToken, error)
|
||||
DeleteRefreshTokenByID(ctx context.Context, tokenID uuid.UUID) error
|
||||
DeleteRefreshTokenByUserID(ctx context.Context, userID uuid.UUID) error
|
||||
|
||||
SetTaskGroupName(ctx context.Context, arg SetTaskGroupNameParams) (TaskGroup, error)
|
||||
DeleteTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
|
||||
DeleteTasksByTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) (int64, error)
|
||||
UpdateTaskGroupLocation(ctx context.Context, arg UpdateTaskGroupLocationParams) (TaskGroup, error)
|
||||
CreateTaskGroup(ctx context.Context, arg CreateTaskGroupParams) (TaskGroup, error)
|
||||
GetAllTaskGroups(ctx context.Context) ([]TaskGroup, error)
|
||||
GetTaskGroupsForProject(ctx context.Context, projectID uuid.UUID) ([]TaskGroup, error)
|
||||
GetTaskGroupByID(ctx context.Context, taskGroupID uuid.UUID) (TaskGroup, error)
|
||||
|
||||
GetAllOrganizations(ctx context.Context) ([]Organization, error)
|
||||
CreateOrganization(ctx context.Context, arg CreateOrganizationParams) (Organization, error)
|
||||
|
||||
GetTeamsForOrganization(ctx context.Context, organizationID uuid.UUID) ([]Team, error)
|
||||
|
||||
CreateTask(ctx context.Context, arg CreateTaskParams) (Task, error)
|
||||
GetTaskByID(ctx context.Context, taskID uuid.UUID) (Task, error)
|
||||
GetAllTasks(ctx context.Context) ([]Task, error)
|
||||
GetTasksForTaskGroupID(ctx context.Context, taskGroupID uuid.UUID) ([]Task, error)
|
||||
UpdateTaskLocation(ctx context.Context, arg UpdateTaskLocationParams) (Task, error)
|
||||
DeleteTaskByID(ctx context.Context, taskID uuid.UUID) error
|
||||
UpdateTaskName(ctx context.Context, arg UpdateTaskNameParams) (Task, error)
|
||||
UpdateTaskDescription(ctx context.Context, arg UpdateTaskDescriptionParams) (Task, error)
|
||||
|
||||
CreateTaskLabelForTask(ctx context.Context, arg CreateTaskLabelForTaskParams) (TaskLabel, error)
|
||||
GetTaskLabelsForTaskID(ctx context.Context, taskID uuid.UUID) ([]TaskLabel, error)
|
||||
GetLabelColorByID(ctx context.Context, labelColorID uuid.UUID) (LabelColor, error)
|
||||
|
||||
CreateTaskAssigned(ctx context.Context, arg CreateTaskAssignedParams) (TaskAssigned, error)
|
||||
GetAssignedMembersForTask(ctx context.Context, taskID uuid.UUID) ([]TaskAssigned, error)
|
||||
DeleteTaskAssignedByID(ctx context.Context, arg DeleteTaskAssignedByIDParams) (TaskAssigned, error)
|
||||
}
|
||||
|
||||
type repoSvc struct {
|
||||
*Queries
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
// NewRepository returns an implementation of the Repository interface.
|
||||
func NewRepository(db *sqlx.DB) Repository {
|
||||
return &repoSvc{
|
||||
Queries: New(db.DB),
|
||||
db: db,
|
||||
}
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: project.sql
|
||||
|
||||
package pg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createProject = `-- name: CreateProject :one
|
||||
INSERT INTO project(owner, team_id, created_at, name) VALUES ($1, $2, $3, $4) RETURNING project_id, team_id, created_at, name, owner
|
||||
`
|
||||
|
||||
type CreateProjectParams struct {
|
||||
Owner uuid.UUID `json:"owner"`
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateProject(ctx context.Context, arg CreateProjectParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, createProject,
|
||||
arg.Owner,
|
||||
arg.TeamID,
|
||||
arg.CreatedAt,
|
||||
arg.Name,
|
||||
)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteProjectByID = `-- name: DeleteProjectByID :exec
|
||||
DELETE FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteProjectByID(ctx context.Context, projectID uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteProjectByID, projectID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getAllProjects = `-- name: GetAllProjects :many
|
||||
SELECT project_id, team_id, created_at, name, owner FROM project
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllProjects(ctx context.Context) ([]Project, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getAllProjects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Project
|
||||
for rows.Next() {
|
||||
var i Project
|
||||
if err := rows.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getAllProjectsForTeam = `-- name: GetAllProjectsForTeam :many
|
||||
SELECT project_id, team_id, created_at, name, owner FROM project WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetAllProjectsForTeam(ctx context.Context, teamID uuid.UUID) ([]Project, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getAllProjectsForTeam, teamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []Project
|
||||
for rows.Next() {
|
||||
var i Project
|
||||
if err := rows.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getProjectByID = `-- name: GetProjectByID :one
|
||||
SELECT project_id, team_id, created_at, name, owner FROM project WHERE project_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, getProjectByID, projectID)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateProjectNameByID = `-- name: UpdateProjectNameByID :one
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING project_id, team_id, created_at, name, owner
|
||||
`
|
||||
|
||||
type UpdateProjectNameByIDParams struct {
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateProjectNameByID(ctx context.Context, arg UpdateProjectNameByIDParams) (Project, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateProjectNameByID, arg.ProjectID, arg.Name)
|
||||
var i Project
|
||||
err := row.Scan(
|
||||
&i.ProjectID,
|
||||
&i.TeamID,
|
||||
&i.CreatedAt,
|
||||
&i.Name,
|
||||
&i.Owner,
|
||||
)
|
||||
return i, err
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// source: team_member.sql
|
||||
|
||||
package pg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const createTeamMember = `-- name: CreateTeamMember :one
|
||||
INSERT INTO team_member (team_id, user_id, addedDate) VALUES ($1, $2, $3)
|
||||
RETURNING team_member_id, team_id, user_id, addeddate
|
||||
`
|
||||
|
||||
type CreateTeamMemberParams struct {
|
||||
TeamID uuid.UUID `json:"team_id"`
|
||||
UserID uuid.UUID `json:"user_id"`
|
||||
Addeddate time.Time `json:"addeddate"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateTeamMember(ctx context.Context, arg CreateTeamMemberParams) (TeamMember, error) {
|
||||
row := q.db.QueryRowContext(ctx, createTeamMember, arg.TeamID, arg.UserID, arg.Addeddate)
|
||||
var i TeamMember
|
||||
err := row.Scan(
|
||||
&i.TeamMemberID,
|
||||
&i.TeamID,
|
||||
&i.UserID,
|
||||
&i.Addeddate,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteTeamMemberByUserID = `-- name: DeleteTeamMemberByUserID :exec
|
||||
DELETE FROM team_member WHERE user_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) DeleteTeamMemberByUserID(ctx context.Context, userID uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteTeamMemberByUserID, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getTeamMembersForTeamID = `-- name: GetTeamMembersForTeamID :many
|
||||
SELECT team_member_id, team_id, user_id, addeddate FROM team_member WHERE team_id = $1
|
||||
`
|
||||
|
||||
func (q *Queries) GetTeamMembersForTeamID(ctx context.Context, teamID uuid.UUID) ([]TeamMember, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getTeamMembersForTeamID, teamID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []TeamMember
|
||||
for rows.Next() {
|
||||
var i TeamMember
|
||||
if err := rows.Scan(
|
||||
&i.TeamMemberID,
|
||||
&i.TeamID,
|
||||
&i.UserID,
|
||||
&i.Addeddate,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
-- name: GetAllProjects :many
|
||||
SELECT * FROM project;
|
||||
|
||||
-- name: GetAllProjectsForTeam :many
|
||||
SELECT * FROM project WHERE team_id = $1;
|
||||
|
||||
-- name: GetProjectByID :one
|
||||
SELECT * FROM project WHERE project_id = $1;
|
||||
|
||||
-- name: CreateProject :one
|
||||
INSERT INTO project(owner, team_id, created_at, name) VALUES ($1, $2, $3, $4) RETURNING *;
|
||||
|
||||
-- name: UpdateProjectNameByID :one
|
||||
UPDATE project SET name = $2 WHERE project_id = $1 RETURNING *;
|
||||
|
||||
-- name: DeleteProjectByID :exec
|
||||
DELETE FROM project WHERE project_id = $1;
|
@ -1,9 +0,0 @@
|
||||
-- name: CreateTeamMember :one
|
||||
INSERT INTO team_member (team_id, user_id, addedDate) VALUES ($1, $2, $3)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetTeamMembersForTeamID :many
|
||||
SELECT * FROM team_member WHERE team_id = $1;
|
||||
|
||||
-- name: DeleteTeamMemberByUserID :exec
|
||||
DELETE FROM team_member WHERE user_id = $1;
|
@ -1,13 +0,0 @@
|
||||
package router
|
||||
|
||||
type ErrExpiredToken struct{}
|
||||
|
||||
func (r *ErrExpiredToken) Error() string {
|
||||
return "token is expired"
|
||||
}
|
||||
|
||||
type ErrMalformedToken struct{}
|
||||
|
||||
func (r *ErrMalformedToken) Error() string {
|
||||
return "token is malformed"
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package router
|
||||
|
||||
import "github.com/jordanknott/project-citadel/api/pg"
|
||||
|
||||
type CitadelHandler struct {
|
||||
repo pg.Repository
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
type AccessTokenClaims struct {
|
||||
UserID string `json:"userId"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type RefreshTokenClaims struct {
|
||||
UserID string `json:"userId"`
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
type LoginRequestData struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type LoginResponseData struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
}
|
||||
|
||||
type LogoutResponseData struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
type RefreshTokenResponseData struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
}
|
||||
|
||||
type AvatarUploadResponseData struct {
|
||||
UserID string `json:"userID"`
|
||||
URL string `json:"url"`
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jmoiron/sqlx"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/jordanknott/project-citadel/api/graph"
|
||||
"github.com/jordanknott/project-citadel/api/pg"
|
||||
)
|
||||
|
||||
func (h *CitadelHandler) PingHandler(w http.ResponseWriter, r *http.Request) {
|
||||
w.Write([]byte("pong"))
|
||||
}
|
||||
|
||||
func (h *CitadelHandler) ProfileImageUpload(w http.ResponseWriter, r *http.Request) {
|
||||
log.Info("preparing to upload file")
|
||||
userID, ok := r.Context().Value("userID").(uuid.UUID)
|
||||
if !ok {
|
||||
log.Error("not a valid uuid")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Parse our multipart form, 10 << 20 specifies a maximum
|
||||
// upload of 10 MB files.
|
||||
r.ParseMultipartForm(10 << 20)
|
||||
|
||||
file, handler, err := r.FormFile("file")
|
||||
if err != nil {
|
||||
log.WithError(err).Error("issue while uploading file")
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
log.WithFields(log.Fields{"filename": handler.Filename, "size": handler.Size, "header": handler.Header}).Info("file metadata")
|
||||
|
||||
fileBytes, err := ioutil.ReadAll(file)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("while reading file")
|
||||
return
|
||||
}
|
||||
err = ioutil.WriteFile("uploads/"+handler.Filename, fileBytes, 0644)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("while reading file")
|
||||
return
|
||||
}
|
||||
|
||||
h.repo.UpdateUserAccountProfileAvatarURL(r.Context(), pg.UpdateUserAccountProfileAvatarURLParams{UserID: userID, ProfileAvatarUrl: sql.NullString{String: "http://localhost:3333/uploads/" + handler.Filename, Valid: true}})
|
||||
// return that we have successfully uploaded our file!
|
||||
log.Info("file uploaded")
|
||||
json.NewEncoder(w).Encode(AvatarUploadResponseData{URL: "http://localhost:3333/uploads/" + handler.Filename, UserID: userID.String()})
|
||||
|
||||
}
|
||||
|
||||
func NewRouter(db *sqlx.DB) (chi.Router, error) {
|
||||
formatter := new(log.TextFormatter)
|
||||
formatter.TimestampFormat = "02-01-2006 15:04:05"
|
||||
formatter.FullTimestamp = true
|
||||
|
||||
routerLogger := log.New()
|
||||
routerLogger.SetLevel(log.DebugLevel)
|
||||
routerLogger.Formatter = formatter
|
||||
r := chi.NewRouter()
|
||||
cors := cors.New(cors.Options{
|
||||
// AllowedOrigins: []string{"https://foo.com"}, // Use this to allow specific origin hosts
|
||||
AllowedOrigins: []string{"*"},
|
||||
// AllowOriginFunc: func(r *http.Request, origin string) bool { return true },
|
||||
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "Cookie"},
|
||||
ExposedHeaders: []string{"Link"},
|
||||
AllowCredentials: true,
|
||||
MaxAge: 300, // Maximum value not ignored by any of major browsers
|
||||
})
|
||||
r.Use(cors.Handler)
|
||||
r.Use(middleware.RequestID)
|
||||
r.Use(middleware.RealIP)
|
||||
r.Use(NewStructuredLogger(routerLogger))
|
||||
r.Use(middleware.Recoverer)
|
||||
r.Use(middleware.Timeout(60 * time.Second))
|
||||
|
||||
repository := pg.NewRepository(db)
|
||||
citadelHandler := CitadelHandler{repository}
|
||||
|
||||
r.Group(func(mux chi.Router) {
|
||||
mux.Mount("/auth", authResource{}.Routes(citadelHandler))
|
||||
mux.Handle("/__graphql", graph.NewPlaygroundHandler("/graphql"))
|
||||
var imgServer = http.FileServer(http.Dir("./uploads/"))
|
||||
mux.Mount("/uploads/", http.StripPrefix("/uploads/", imgServer))
|
||||
|
||||
})
|
||||
r.Group(func(mux chi.Router) {
|
||||
mux.Use(AuthenticationMiddleware)
|
||||
mux.Post("/users/me/avatar", citadelHandler.ProfileImageUpload)
|
||||
mux.Get("/ping", citadelHandler.PingHandler)
|
||||
mux.Handle("/graphql", graph.NewHandler(repository))
|
||||
})
|
||||
|
||||
return r, nil
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
version: "1"
|
||||
packages:
|
||||
- name: "pg"
|
||||
- name: "db"
|
||||
emit_json_tags: true
|
||||
emit_prepared_queries: false
|
||||
emit_interface: true
|
||||
path: "pg"
|
||||
queries: "./query/"
|
||||
path: "internal/db"
|
||||
queries: "./internal/db/query/"
|
||||
schema: "./migrations/"
|
||||
|
||||
|
12
api/templates/mail/user/registered.tmpl
Normal file
12
api/templates/mail/user/registered.tmpl
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>{{.Username}} has been registered</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Hi <b>{{.Username}}</b>, thanks for registering at {{.AppName}}!</p>
|
||||
<p>© {{.Year}} <a target="_blank" rel="noopener noreferrer" href="{{.AppURL}}">{{.AppName}}</a></p>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user