feat: add tenant and user management with migrations, handlers, and tests
- Implemented tenant and user management features including: - Tenant creation and management with associated migrations. - User creation and management with associated migrations. - Tenant membership management with associated migrations. - Platform user roles management with associated migrations. - Quota management with associated migrations. - Article and template management with associated migrations. - Added HTTP handlers for templates and workspaces. - Created tests for protected and public routes. - Introduced a script to check tenant scope in SQL queries. - Documented task plan for backend completion and frontend foundation.
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/tenant/repository/generated"
|
||||
)
|
||||
|
||||
type UserRecord struct {
|
||||
ID int64
|
||||
Email string
|
||||
Phone *string
|
||||
PasswordHash string
|
||||
Name string
|
||||
AvatarURL *string
|
||||
Status string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type MembershipRecord struct {
|
||||
ID int64
|
||||
TenantID int64
|
||||
UserID int64
|
||||
TenantRole string
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type AuthRepository interface {
|
||||
GetUserByEmail(ctx context.Context, email string) (*UserRecord, error)
|
||||
GetUserByID(ctx context.Context, id int64) (*UserRecord, error)
|
||||
GetTenantMembership(ctx context.Context, userID int64) (*MembershipRecord, error)
|
||||
GetTenantMembershipByTenantAndUser(ctx context.Context, tenantID, userID int64) (*MembershipRecord, error)
|
||||
}
|
||||
|
||||
type authRepository struct {
|
||||
q generated.Querier
|
||||
}
|
||||
|
||||
func NewAuthRepository(db generated.DBTX) AuthRepository {
|
||||
return &authRepository{q: newQuerier(db)}
|
||||
}
|
||||
|
||||
func (r *authRepository) GetUserByEmail(ctx context.Context, email string) (*UserRecord, error) {
|
||||
row, err := r.q.GetUserByEmail(ctx, email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UserRecord{
|
||||
ID: row.ID,
|
||||
Email: row.Email,
|
||||
Phone: nullableText(row.Phone),
|
||||
PasswordHash: row.PasswordHash,
|
||||
Name: row.Name,
|
||||
AvatarURL: nullableText(row.AvatarUrl),
|
||||
Status: row.Status,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *authRepository) GetUserByID(ctx context.Context, id int64) (*UserRecord, error) {
|
||||
row, err := r.q.GetUserByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &UserRecord{
|
||||
ID: row.ID,
|
||||
Email: row.Email,
|
||||
Phone: nullableText(row.Phone),
|
||||
PasswordHash: row.PasswordHash,
|
||||
Name: row.Name,
|
||||
AvatarURL: nullableText(row.AvatarUrl),
|
||||
Status: row.Status,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *authRepository) GetTenantMembership(ctx context.Context, userID int64) (*MembershipRecord, error) {
|
||||
row, err := r.q.GetTenantMembership(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &MembershipRecord{
|
||||
ID: row.ID,
|
||||
TenantID: row.TenantID,
|
||||
UserID: row.UserID,
|
||||
TenantRole: row.TenantRole,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *authRepository) GetTenantMembershipByTenantAndUser(ctx context.Context, tenantID, userID int64) (*MembershipRecord, error) {
|
||||
row, err := r.q.GetTenantMembershipByTenantAndUser(ctx, generated.GetTenantMembershipByTenantAndUserParams{
|
||||
TenantID: tenantID,
|
||||
UserID: userID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &MembershipRecord{
|
||||
ID: row.ID,
|
||||
TenantID: row.TenantID,
|
||||
UserID: row.UserID,
|
||||
TenantRole: row.TenantRole,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user