daddy/internal/command/create_user.go
William Petit 3fd8bf7e69 Auto-création du compte utilisateur à la première connexion
- Sauvegarde de l'adresse courriel de l'utilisateur en session
- Implémentation d'une première Query GraphQL pour récupérer le profil
  de l'utilisateur connecté
- Utilisation de la pattern CQRS pour les commandes/requêtes sur la base
  de données
2020-07-13 14:44:05 +02:00

100 lines
2.0 KiB
Go

package command
import (
"context"
"github.com/jackc/pgx/v4/pgxpool"
"forge.cadoles.com/Cadoles/daddy/internal/database"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/cqrs"
"gitlab.com/wpetit/goweb/middleware/container"
)
const (
createConnectedUserStatement = `
INSERT INTO users (email, connected_at) VALUES ($1, now())
ON CONFLICT ON CONSTRAINT unique_email
DO UPDATE SET connected_at = now();
`
createUserStatement = `
INSERT INTO users (email) VALUES ($1)
ON CONFLICT ON CONSTRAINT unique_email
DO NOTHING;
`
)
type CreateUserCommandRequest struct {
Email string
Connected bool
}
func HandleCreateUserCommand(ctx context.Context, cmd cqrs.Command) error {
req, ok := cmd.Request().(*CreateUserCommandRequest)
if !ok {
return errors.WithStack(cqrs.ErrUnexpectedRequest)
}
ctn, err := container.From(ctx)
if err != nil {
return errors.WithStack(err)
}
pool, err := database.From(ctn)
if err != nil {
return errors.WithStack(err)
}
conn, err := pool.Acquire(ctx)
if err != nil {
return errors.WithStack(err)
}
defer conn.Release()
if req.Connected {
if err := createConnectedUser(ctx, conn, req.Email); err != nil {
return errors.WithStack(err)
}
} else {
if err := createUser(ctx, conn, req.Email); err != nil {
return errors.WithStack(err)
}
}
return nil
}
func createConnectedUser(ctx context.Context, conn *pgxpool.Conn, email string) error {
_, err := conn.Conn().Prepare(
ctx, "create_connected_user",
createConnectedUserStatement,
)
if err != nil {
return errors.WithStack(err)
}
if _, err := conn.Exec(ctx, "create_connected_user", email); err != nil {
return errors.WithStack(err)
}
return nil
}
func createUser(ctx context.Context, conn *pgxpool.Conn, email string) error {
_, err := conn.Conn().Prepare(
ctx, "create_user",
createUserStatement,
)
if err != nil {
return errors.WithStack(err)
}
if _, err := conn.Exec(ctx, "create_user", email); err != nil {
return errors.WithStack(err)
}
return nil
}