1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-06 23:46:29 +02:00

147 lines
4.2 KiB
Go

package user_account
import (
"context"
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
"github.com/huandu/go-sqlbuilder"
"github.com/pkg/errors"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
)
// UserFindByAccount lists all the users for a given account ID.
func (repo *Repository) UserFindByAccount(ctx context.Context, claims auth.Claims, req UserFindByAccountRequest) (Users, error) {
span, ctx := tracer.StartSpanFromContext(ctx, "internal.user_account.UserFindByAccount")
defer span.Finish()
v := webcontext.Validator()
// Validate the request.
err := v.StructCtx(ctx, req)
if err != nil {
return nil, err
}
/*
SELECT
id,
first_name,
last_name,
name,
email,
timezone,
account_id,
status,
roles,
created_at,
updated_at,
archived_at FROM (
SELECT
u.id,
u.first_name,
u.last_name,
concat(u.first_name, ' ',u.last_name) as name,
u.email,
u.timezone,
ua.account_id,
ua.status,
ua.roles,
CASE WHEN ua.created_at > u.created_at THEN ua.created_at ELSE u.created_at END AS created_at,
CASE WHEN ua.updated_at > u.updated_at THEN ua.updated_at ELSE u.updated_at END AS updated_at,
CASE WHEN ua.archived_at > u.archived_at THEN ua.archived_at ELSE u.archived_at END AS archived_at
FROM users u
JOIN users_accounts ua
ON u.id = ua.user_id AND ua.account_id = 'df1a8a65-b00b-4640-9a64-66c1a355b17c'
WHERE
(u.archived_at IS NULL AND ua.archived_at IS NULL) AND
account_id IN (SELECT account_id FROM users_accounts WHERE (account_id = ? OR user_id = ?))
) res ORDER BY id asc
*/
subQuery := sqlbuilder.NewSelectBuilder().
Select("u.id,u.first_name,u.last_name,concat(u.first_name, ' ',u.last_name) as name,u.email,u.timezone,ua.account_id,ua.status,ua.roles,"+
"CASE WHEN ua.created_at > u.created_at THEN ua.created_at ELSE u.created_at END AS created_at,"+
"CASE WHEN ua.updated_at > u.updated_at THEN ua.updated_at ELSE u.updated_at END AS updated_at,"+
"CASE WHEN ua.archived_at > u.archived_at THEN ua.archived_at ELSE u.archived_at END AS archived_at").
From(userTableName+" u").
Join(userAccountTableName+" ua", "u.id = ua.user_id", "ua.account_id = '"+req.AccountID+"'")
if !req.IncludeArchived {
subQuery.Where(subQuery.And(
subQuery.IsNull("u.archived_at"),
subQuery.IsNull("ua.archived_at")))
}
if claims.Audience != "" || claims.Subject != "" {
// Build select statement for users_accounts table
authQuery := sqlbuilder.NewSelectBuilder().Select("account_id").From(userAccountTableName)
var or []string
if claims.Audience != "" {
or = append(or, authQuery.Equal("account_id", claims.Audience))
}
if claims.Subject != "" {
or = append(or, authQuery.Equal("user_id", claims.Subject))
}
// Append sub query
if len(or) > 0 {
authQuery.Where(authQuery.Or(or...))
subQuery.Where(subQuery.In("account_id", authQuery))
}
}
subQueryStr, queryArgs := subQuery.Build()
query := sqlbuilder.NewSelectBuilder().
Select("id,first_name,last_name,name,email,timezone,account_id,status,roles,created_at,updated_at,archived_at").
From("(" + subQueryStr + ") res")
if req.Where != "" {
query.Where(query.And(req.Where))
}
if len(req.Order) > 0 {
query.OrderBy(req.Order...)
}
if req.Limit != nil {
query.Limit(int(*req.Limit))
}
if req.Offset != nil {
query.Offset(int(*req.Offset))
}
queryStr, moreQueryArgs := query.Build()
queryStr = repo.DbConn.Rebind(queryStr)
queryArgs = append(queryArgs, moreQueryArgs...)
// fetch all places from the db
rows, err := repo.DbConn.QueryContext(ctx, queryStr, queryArgs...)
if err != nil {
err = errors.Wrapf(err, "query - %s", query.String())
err = errors.WithMessage(err, "find users failed")
return nil, err
}
// iterate over each row
resp := []*User{}
for rows.Next() {
var (
u User
err error
)
err = rows.Scan(&u.ID, &u.FirstName, &u.LastName, &u.Name, &u.Email, &u.Timezone, &u.AccountID, &u.Status,
&u.Roles, &u.CreatedAt, &u.UpdatedAt, &u.ArchivedAt)
if err != nil {
err = errors.Wrapf(err, "query - %s", query.String())
return nil, err
}
resp = append(resp, &u)
}
return resp, nil
}