feat: add wallet settlement audit flow
This commit is contained in:
@@ -22,13 +22,15 @@ type Store struct {
|
||||
}
|
||||
|
||||
var (
|
||||
ErrInvalidCredentials = errors.New("invalid account or password")
|
||||
ErrInvalidInvitation = errors.New("invalid or expired invitation code")
|
||||
ErrAccessRuleResourceDenied = errors.New("access rule resource is not available")
|
||||
ErrLocalUserRequired = errors.New("local gateway user is required")
|
||||
ErrProtectedDefault = errors.New("protected default resource cannot be deleted")
|
||||
ErrUserAlreadyExists = errors.New("user already exists")
|
||||
ErrWeakPassword = errors.New("password must be at least 8 characters")
|
||||
ErrInvalidCredentials = errors.New("invalid account or password")
|
||||
ErrInvalidInvitation = errors.New("invalid or expired invitation code")
|
||||
ErrAccessRuleResourceDenied = errors.New("access rule resource is not available")
|
||||
ErrInsufficientWalletBalance = errors.New("insufficient wallet balance")
|
||||
ErrLocalUserRequired = errors.New("local gateway user is required")
|
||||
ErrWalletBalanceUnchanged = errors.New("wallet balance unchanged")
|
||||
ErrProtectedDefault = errors.New("protected default resource cannot be deleted")
|
||||
ErrUserAlreadyExists = errors.New("user already exists")
|
||||
ErrWeakPassword = errors.New("password must be at least 8 characters")
|
||||
)
|
||||
|
||||
func Connect(ctx context.Context, databaseURL string) (*Store, error) {
|
||||
@@ -298,28 +300,29 @@ type LocalLoginInput struct {
|
||||
}
|
||||
|
||||
type GatewayUser struct {
|
||||
ID string `json:"id"`
|
||||
UserKey string `json:"userKey"`
|
||||
Source string `json:"source"`
|
||||
ExternalUserID string `json:"externalUserId,omitempty"`
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
AvatarURL string `json:"avatarUrl,omitempty"`
|
||||
GatewayTenantID string `json:"gatewayTenantId,omitempty"`
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
TenantKey string `json:"tenantKey,omitempty"`
|
||||
DefaultUserGroupID string `json:"defaultUserGroupId,omitempty"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
AuthProfile map[string]any `json:"authProfile,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
Status string `json:"status"`
|
||||
LastLoginAt string `json:"lastLoginAt,omitempty"`
|
||||
SyncedAt string `json:"syncedAt,omitempty"`
|
||||
SourceUpdatedAt string `json:"sourceUpdatedAt,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ID string `json:"id"`
|
||||
UserKey string `json:"userKey"`
|
||||
Source string `json:"source"`
|
||||
ExternalUserID string `json:"externalUserId,omitempty"`
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"displayName,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Phone string `json:"phone,omitempty"`
|
||||
AvatarURL string `json:"avatarUrl,omitempty"`
|
||||
GatewayTenantID string `json:"gatewayTenantId,omitempty"`
|
||||
TenantID string `json:"tenantId,omitempty"`
|
||||
TenantKey string `json:"tenantKey,omitempty"`
|
||||
DefaultUserGroupID string `json:"defaultUserGroupId,omitempty"`
|
||||
Roles []string `json:"roles,omitempty"`
|
||||
AuthProfile map[string]any `json:"authProfile,omitempty"`
|
||||
Metadata map[string]any `json:"metadata,omitempty"`
|
||||
WalletAccounts []GatewayWalletAccount `json:"walletAccounts,omitempty"`
|
||||
Status string `json:"status"`
|
||||
LastLoginAt string `json:"lastLoginAt,omitempty"`
|
||||
SyncedAt string `json:"syncedAt,omitempty"`
|
||||
SourceUpdatedAt string `json:"sourceUpdatedAt,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type UserGroup struct {
|
||||
@@ -927,10 +930,31 @@ SELECT id::text, user_key, source, COALESCE(external_user_id, ''), username,
|
||||
COALESCE(gateway_tenant_id::text, ''), COALESCE(tenant_id, ''), COALESCE(tenant_key, ''),
|
||||
COALESCE(default_user_group_id::text, ''), roles, auth_profile, metadata,
|
||||
status, COALESCE(last_login_at::text, ''), COALESCE(synced_at::text, ''), COALESCE(source_updated_at::text, ''),
|
||||
created_at, updated_at
|
||||
FROM gateway_users
|
||||
WHERE deleted_at IS NULL
|
||||
ORDER BY created_at DESC`)
|
||||
created_at, updated_at, COALESCE(wallets.wallet_accounts, '[]'::jsonb)
|
||||
FROM gateway_users u
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT jsonb_agg(jsonb_build_object(
|
||||
'id', a.id::text,
|
||||
'gatewayTenantId', COALESCE(a.gateway_tenant_id::text, ''),
|
||||
'gatewayUserId', a.gateway_user_id::text,
|
||||
'tenantId', COALESCE(a.tenant_id, ''),
|
||||
'tenantKey', COALESCE(a.tenant_key, ''),
|
||||
'userId', COALESCE(a.user_id, ''),
|
||||
'currency', a.currency,
|
||||
'balance', a.balance::float8,
|
||||
'frozenBalance', a.frozen_balance::float8,
|
||||
'totalRecharged', a.total_recharged::float8,
|
||||
'totalSpent', a.total_spent::float8,
|
||||
'status', a.status,
|
||||
'metadata', a.metadata,
|
||||
'createdAt', a.created_at,
|
||||
'updatedAt', a.updated_at
|
||||
) ORDER BY a.currency ASC) AS wallet_accounts
|
||||
FROM gateway_wallet_accounts a
|
||||
WHERE a.gateway_user_id = u.id
|
||||
) wallets ON true
|
||||
WHERE u.deleted_at IS NULL
|
||||
ORDER BY u.created_at DESC`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -942,6 +966,7 @@ ORDER BY created_at DESC`)
|
||||
var roles []byte
|
||||
var authProfile []byte
|
||||
var metadata []byte
|
||||
var walletAccounts []byte
|
||||
if err := rows.Scan(
|
||||
&item.ID,
|
||||
&item.UserKey,
|
||||
@@ -965,12 +990,14 @@ ORDER BY created_at DESC`)
|
||||
&item.SourceUpdatedAt,
|
||||
&item.CreatedAt,
|
||||
&item.UpdatedAt,
|
||||
&walletAccounts,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
item.Roles = decodeStringArray(roles)
|
||||
item.AuthProfile = decodeObject(authProfile)
|
||||
item.Metadata = decodeObject(metadata)
|
||||
item.WalletAccounts = decodeWalletAccounts(walletAccounts)
|
||||
items = append(items, item)
|
||||
}
|
||||
return items, rows.Err()
|
||||
|
||||
Reference in New Issue
Block a user