fix: user profile not rendering in top navbar
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
"github.com/golang-migrate/migrate/v4/source/httpfs"
|
||||
@ -30,9 +31,13 @@ func newWebCmd() *cobra.Command {
|
||||
log.SetFormatter(Formatter)
|
||||
log.SetLevel(log.InfoLevel)
|
||||
|
||||
connection := config.GetDatabaseConnectionUri()
|
||||
appConfig, err := config.GetAppConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
connection := appConfig.Database.GetDatabaseConnectionUri()
|
||||
var db *sqlx.DB
|
||||
var err error
|
||||
var retryDuration time.Duration
|
||||
maxRetryNumber := 4
|
||||
for i := 0; i < maxRetryNumber; i++ {
|
||||
@ -61,11 +66,16 @@ func newWebCmd() *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
appConfig, err := config.GetAppConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
var server *machinery.Server
|
||||
if appConfig.Job.Enabled {
|
||||
jobConfig := appConfig.Job.GetJobConfig()
|
||||
server, err = machinery.NewServer(&jobConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
r, _ := route.NewRouter(db, appConfig)
|
||||
|
||||
r, _ := route.NewRouter(db, server, appConfig)
|
||||
log.WithFields(log.Fields{"url": viper.GetString("server.hostname")}).Info("starting server")
|
||||
return http.ListenAndServe(viper.GetString("server.hostname"), r)
|
||||
},
|
||||
|
@ -1,18 +1,16 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
"github.com/RichardKnop/machinery/v1/config"
|
||||
queueLog "github.com/RichardKnop/machinery/v1/log"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/jordanknott/taskcafe/internal/config"
|
||||
repo "github.com/jordanknott/taskcafe/internal/db"
|
||||
"github.com/jordanknott/taskcafe/internal/notification"
|
||||
"github.com/jordanknott/taskcafe/internal/jobs"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@ -28,13 +26,11 @@ func newWorkerCmd() *cobra.Command {
|
||||
log.SetFormatter(Formatter)
|
||||
log.SetLevel(log.InfoLevel)
|
||||
|
||||
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s sslmode=disable",
|
||||
viper.GetString("database.user"),
|
||||
viper.GetString("database.password"),
|
||||
viper.GetString("database.host"),
|
||||
viper.GetString("database.name"),
|
||||
)
|
||||
db, err := sqlx.Connect("postgres", connection)
|
||||
appConfig, err := config.GetAppConfig()
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
db, err := sqlx.Connect("postgres", config.GetDatabaseConfig().GetDatabaseConnectionUri())
|
||||
if err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
@ -43,25 +39,15 @@ func newWorkerCmd() *cobra.Command {
|
||||
db.SetConnMaxLifetime(5 * time.Minute)
|
||||
defer db.Close()
|
||||
|
||||
var cnf = &config.Config{
|
||||
Broker: viper.GetString("queue.broker"),
|
||||
DefaultQueue: "machinery_tasks",
|
||||
ResultBackend: viper.GetString("queue.store"),
|
||||
AMQP: &config.AMQPConfig{
|
||||
Exchange: "machinery_exchange",
|
||||
ExchangeType: "direct",
|
||||
BindingKey: "machinery_task",
|
||||
},
|
||||
}
|
||||
|
||||
log.Info("starting task queue server instance")
|
||||
server, err := machinery.NewServer(cnf)
|
||||
jobConfig := appConfig.Job.GetJobConfig()
|
||||
server, err := machinery.NewServer(&jobConfig)
|
||||
if err != nil {
|
||||
// do something with the error
|
||||
}
|
||||
queueLog.Set(¬ification.MachineryLogger{})
|
||||
queueLog.Set(&jobs.MachineryLogger{})
|
||||
repo := *repo.NewRepository(db)
|
||||
notification.RegisterTasks(server, repo)
|
||||
jobs.RegisterTasks(server, repo)
|
||||
|
||||
worker := server.NewWorker("taskcafe_worker", 10)
|
||||
log.Info("starting task queue worker")
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
mConfig "github.com/RichardKnop/machinery/v1/config"
|
||||
"github.com/google/uuid"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
@ -22,8 +23,10 @@ const (
|
||||
SecurityTokenExpiration = "security.token_expiration"
|
||||
SecuritySecret = "security.secret"
|
||||
|
||||
QueueBroker = "queue.broker"
|
||||
QueueStore = "queue.store"
|
||||
JobEnabled = "job.enabled"
|
||||
JobBroker = "job.broker"
|
||||
JobStore = "job.store"
|
||||
JobQueueName = "job.queue_name"
|
||||
|
||||
SmtpFrom = "smtp.from"
|
||||
SmtpHost = "smtp.host"
|
||||
@ -33,7 +36,7 @@ const (
|
||||
SmtpSkipVerify = "false"
|
||||
)
|
||||
|
||||
var defaults = map[string]string{
|
||||
var defaults = map[string]interface{}{
|
||||
ServerHostname: "0.0.0.0:3333",
|
||||
DatabaseHost: "127.0.0.1",
|
||||
DatabaseName: "taskcafe",
|
||||
@ -43,14 +46,16 @@ var defaults = map[string]string{
|
||||
DatabaseSslMode: "disable",
|
||||
SecurityTokenExpiration: "15m",
|
||||
SecuritySecret: "",
|
||||
QueueBroker: "amqp://guest:guest@localhost:5672/",
|
||||
QueueStore: "memcache://localhost:11211",
|
||||
JobEnabled: false,
|
||||
JobBroker: "amqp://guest:guest@localhost:5672/",
|
||||
JobStore: "memcache://localhost:11211",
|
||||
JobQueueName: "taskcafe_tasks",
|
||||
SmtpFrom: "no-reply@example.com",
|
||||
SmtpHost: "localhost",
|
||||
SmtpPort: "587",
|
||||
SmtpUsername: "",
|
||||
SmtpPassword: "",
|
||||
SmtpSkipVerify: "false",
|
||||
SmtpSkipVerify: false,
|
||||
}
|
||||
|
||||
func InitDefaults() {
|
||||
@ -59,21 +64,40 @@ func InitDefaults() {
|
||||
}
|
||||
}
|
||||
|
||||
func GetDatabaseConnectionUri() string {
|
||||
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s port=%s sslmode=%s",
|
||||
viper.GetString(DatabaseUser),
|
||||
viper.GetString(DatabasePassword),
|
||||
viper.GetString(DatabaseHost),
|
||||
viper.GetString(DatabaseName),
|
||||
viper.GetString(DatabasePort),
|
||||
viper.GetString(DatabaseSslMode),
|
||||
)
|
||||
return connection
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
Email EmailConfig
|
||||
Security SecurityConfig
|
||||
Database DatabaseConfig
|
||||
Job JobConfig
|
||||
}
|
||||
|
||||
type JobConfig struct {
|
||||
Enabled bool
|
||||
Broker string
|
||||
QueueName string
|
||||
Store string
|
||||
}
|
||||
|
||||
func GetJobConfig() JobConfig {
|
||||
return JobConfig{
|
||||
Enabled: viper.GetBool(JobEnabled),
|
||||
Broker: viper.GetString(JobBroker),
|
||||
QueueName: viper.GetString(JobQueueName),
|
||||
Store: viper.GetString(JobStore),
|
||||
}
|
||||
}
|
||||
|
||||
func (cfg *JobConfig) GetJobConfig() mConfig.Config {
|
||||
return mConfig.Config{
|
||||
Broker: cfg.Broker,
|
||||
DefaultQueue: cfg.QueueName,
|
||||
ResultBackend: cfg.Store,
|
||||
AMQP: &mConfig.AMQPConfig{
|
||||
Exchange: "machinery_exchange",
|
||||
ExchangeType: "direct",
|
||||
BindingKey: "machinery_task",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type EmailConfig struct {
|
||||
@ -86,6 +110,27 @@ type EmailConfig struct {
|
||||
InsecureSkipVerify bool
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
Host string
|
||||
Port string
|
||||
Name string
|
||||
Username string
|
||||
Password string
|
||||
SslMode string
|
||||
}
|
||||
|
||||
func (cfg DatabaseConfig) GetDatabaseConnectionUri() string {
|
||||
connection := fmt.Sprintf("user=%s password=%s host=%s dbname=%s port=%s sslmode=%s",
|
||||
cfg.Username,
|
||||
cfg.Password,
|
||||
cfg.Host,
|
||||
cfg.Name,
|
||||
cfg.Port,
|
||||
cfg.SslMode,
|
||||
)
|
||||
return connection
|
||||
}
|
||||
|
||||
type SecurityConfig struct {
|
||||
AccessTokenExpiration time.Duration
|
||||
Secret []byte
|
||||
@ -101,10 +146,14 @@ func GetAppConfig() (AppConfig, error) {
|
||||
if err != nil {
|
||||
return AppConfig{}, err
|
||||
}
|
||||
jobCfg := GetJobConfig()
|
||||
databaseCfg := GetDatabaseConfig()
|
||||
emailCfg := GetEmailConfig()
|
||||
return AppConfig{
|
||||
Email: emailCfg,
|
||||
Security: securityCfg,
|
||||
Database: databaseCfg,
|
||||
Job: jobCfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -119,11 +168,22 @@ func GetSecurityConfig(accessTokenExp string, secret []byte) (SecurityConfig, er
|
||||
|
||||
func GetEmailConfig() EmailConfig {
|
||||
return EmailConfig{
|
||||
From: viper.GetString("smtp.from"),
|
||||
Host: viper.GetString("smtp.host"),
|
||||
Port: viper.GetInt("smtp.port"),
|
||||
Username: viper.GetString("smtp.username"),
|
||||
Password: viper.GetString("smtp.password"),
|
||||
InsecureSkipVerify: viper.GetBool("smtp.skip_verify"),
|
||||
From: viper.GetString(SmtpFrom),
|
||||
Host: viper.GetString(SmtpHost),
|
||||
Port: viper.GetInt(SmtpPort),
|
||||
Username: viper.GetString(SmtpUsername),
|
||||
Password: viper.GetString(SmtpPassword),
|
||||
InsecureSkipVerify: viper.GetBool(SmtpSkipVerify),
|
||||
}
|
||||
}
|
||||
|
||||
func GetDatabaseConfig() DatabaseConfig {
|
||||
return DatabaseConfig{
|
||||
Username: viper.GetString(DatabaseUser),
|
||||
Password: viper.GetString(DatabasePassword),
|
||||
Port: viper.GetString(DatabasePort),
|
||||
SslMode: viper.GetString(DatabaseSslMode),
|
||||
Name: viper.GetString(DatabaseName),
|
||||
Host: viper.GetString(DatabaseHost),
|
||||
}
|
||||
}
|
||||
|
@ -2047,7 +2047,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||
|
||||
return e.complexity.Notified.Read(childComplexity), true
|
||||
|
||||
case "Notified.read_at":
|
||||
case "Notified.readAt":
|
||||
if e.complexity.Notified.ReadAt == nil {
|
||||
break
|
||||
}
|
||||
@ -3185,7 +3185,7 @@ type Notified {
|
||||
id: ID!
|
||||
notification: Notification!
|
||||
read: Boolean!
|
||||
read_at: Time
|
||||
readAt: Time
|
||||
}
|
||||
|
||||
`, BuiltIn: false},
|
||||
@ -12388,7 +12388,7 @@ func (ec *executionContext) _Notified_read(ctx context.Context, field graphql.Co
|
||||
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Notified_read_at(ctx context.Context, field graphql.CollectedField, obj *Notified) (ret graphql.Marshaler) {
|
||||
func (ec *executionContext) _Notified_readAt(ctx context.Context, field graphql.CollectedField, obj *Notified) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
@ -21877,8 +21877,8 @@ func (ec *executionContext) _Notified(ctx context.Context, sel ast.SelectionSet,
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "read_at":
|
||||
out.Values[i] = ec._Notified_read_at(ctx, field, obj)
|
||||
case "readAt":
|
||||
out.Values[i] = ec._Notified_readAt(ctx, field, obj)
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ type Notified struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Notification *db.Notification `json:"notification"`
|
||||
Read bool `json:"read"`
|
||||
ReadAt *time.Time `json:"read_at"`
|
||||
ReadAt *time.Time `json:"readAt"`
|
||||
}
|
||||
|
||||
type OwnedList struct {
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/taskcafe/internal/db"
|
||||
"github.com/jordanknott/taskcafe/internal/logger"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (r *notificationResolver) ID(ctx context.Context, obj *db.Notification) (uuid.UUID, error) {
|
||||
@ -23,7 +24,23 @@ func (r *notificationResolver) ActionType(ctx context.Context, obj *db.Notificat
|
||||
}
|
||||
|
||||
func (r *notificationResolver) CausedBy(ctx context.Context, obj *db.Notification) (*NotificationCausedBy, error) {
|
||||
panic(fmt.Errorf("not implemented"))
|
||||
user, err := r.Repository.GetUserAccountByID(ctx, obj.CausedBy)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return &NotificationCausedBy{
|
||||
Fullname: "Unknown user",
|
||||
Username: "unknown",
|
||||
ID: obj.CausedBy,
|
||||
}, nil
|
||||
}
|
||||
log.WithError(err).Error("error while resolving Notification.CausedBy")
|
||||
return &NotificationCausedBy{}, err
|
||||
}
|
||||
return &NotificationCausedBy{
|
||||
Fullname: user.FullName,
|
||||
Username: user.Username,
|
||||
ID: obj.CausedBy,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *notificationResolver) Data(ctx context.Context, obj *db.Notification) ([]NotificationData, error) {
|
||||
|
@ -33,6 +33,6 @@ type Notified {
|
||||
id: ID!
|
||||
notification: Notification!
|
||||
read: Boolean!
|
||||
read_at: Time
|
||||
readAt: Time
|
||||
}
|
||||
|
||||
|
@ -33,5 +33,5 @@ type Notified {
|
||||
id: ID!
|
||||
notification: Notification!
|
||||
read: Boolean!
|
||||
read_at: Time
|
||||
readAt: Time
|
||||
}
|
||||
|
33
internal/jobs/jobs.go
Normal file
33
internal/jobs/jobs.go
Normal file
@ -0,0 +1,33 @@
|
||||
package jobs
|
||||
|
||||
import (
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/taskcafe/internal/config"
|
||||
"github.com/jordanknott/taskcafe/internal/db"
|
||||
)
|
||||
|
||||
func RegisterTasks(server *machinery.Server, repo db.Repository) {
|
||||
tasks := JobTasks{repo}
|
||||
server.RegisterTasks(map[string]interface{}{
|
||||
"taskMemberWasAdded": tasks.TaskMemberWasAdded,
|
||||
})
|
||||
}
|
||||
|
||||
type JobTasks struct {
|
||||
Repository db.Repository
|
||||
}
|
||||
|
||||
func (t *JobTasks) TaskMemberWasAdded(taskID, notifierID, notifiedID string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
type JobQueue struct {
|
||||
AppConfig config.AppConfig
|
||||
Server *machinery.Server
|
||||
}
|
||||
|
||||
func (q *JobQueue) TaskMemberWasAdded(taskID, notifier, notified uuid.UUID) error {
|
||||
return nil
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package notification
|
||||
package jobs
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
@ -1,31 +0,0 @@
|
||||
package notification
|
||||
|
||||
import (
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jordanknott/taskcafe/internal/db"
|
||||
)
|
||||
|
||||
func RegisterTasks(server *machinery.Server, repo db.Repository) {
|
||||
tasks := NotificationTasks{repo}
|
||||
server.RegisterTasks(map[string]interface{}{
|
||||
"taskMemberWasAdded": tasks.TaskMemberWasAdded,
|
||||
})
|
||||
}
|
||||
|
||||
type NotificationTasks struct {
|
||||
Repository db.Repository
|
||||
}
|
||||
|
||||
func (m *NotificationTasks) TaskMemberWasAdded(taskID, notifierID, notifiedID string) (bool, error) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
type NotificationQueue struct {
|
||||
Server *machinery.Server
|
||||
}
|
||||
|
||||
func (n *NotificationQueue) TaskMemberWasAdded(taskID, notifier, notified uuid.UUID) error {
|
||||
return nil
|
||||
}
|
@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/RichardKnop/machinery/v1"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/cors"
|
||||
@ -66,7 +67,7 @@ type TaskcafeHandler struct {
|
||||
}
|
||||
|
||||
// NewRouter creates a new router for chi
|
||||
func NewRouter(dbConnection *sqlx.DB, appConfig config.AppConfig) (chi.Router, error) {
|
||||
func NewRouter(dbConnection *sqlx.DB, job *machinery.Server, appConfig config.AppConfig) (chi.Router, error) {
|
||||
formatter := new(log.TextFormatter)
|
||||
formatter.TimestampFormat = "02-01-2006 15:04:05"
|
||||
formatter.FullTimestamp = true
|
||||
|
Reference in New Issue
Block a user