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,104 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/geo-platform/tenant-api/internal/tenant/repository/generated"
|
||||
)
|
||||
|
||||
type WorkspaceRecentArticle struct {
|
||||
ID int64
|
||||
GenerateStatus string
|
||||
PublishStatus string
|
||||
SourceType string
|
||||
CreatedAt time.Time
|
||||
Title *string
|
||||
WordCount int
|
||||
SourceLabel *string
|
||||
TemplateName *string
|
||||
}
|
||||
|
||||
type WorkspacePlan struct {
|
||||
PlanCode string
|
||||
PlanName string
|
||||
QuotaPolicyJSON []byte
|
||||
StartAt time.Time
|
||||
EndAt time.Time
|
||||
}
|
||||
|
||||
type WorkspaceRepository interface {
|
||||
CountArticlesByTenant(ctx context.Context, tenantID int64) (int64, error)
|
||||
CountPublishedArticlesByTenant(ctx context.Context, tenantID int64) (int64, error)
|
||||
CountBrandsByTenant(ctx context.Context, tenantID int64) (int64, error)
|
||||
GetRecentArticles(ctx context.Context, tenantID int64) ([]WorkspaceRecentArticle, error)
|
||||
GetQuotaSummary(ctx context.Context, tenantID int64) (int, error)
|
||||
GetActivePlanForTenant(ctx context.Context, tenantID int64) (*WorkspacePlan, error)
|
||||
}
|
||||
|
||||
type workspaceRepository struct {
|
||||
q generated.Querier
|
||||
}
|
||||
|
||||
func NewWorkspaceRepository(db generated.DBTX) WorkspaceRepository {
|
||||
return &workspaceRepository{q: newQuerier(db)}
|
||||
}
|
||||
|
||||
func (r *workspaceRepository) CountArticlesByTenant(ctx context.Context, tenantID int64) (int64, error) {
|
||||
return r.q.CountArticlesByTenant(ctx, tenantID)
|
||||
}
|
||||
|
||||
func (r *workspaceRepository) CountPublishedArticlesByTenant(ctx context.Context, tenantID int64) (int64, error) {
|
||||
return r.q.CountPublishedArticlesByTenant(ctx, tenantID)
|
||||
}
|
||||
|
||||
func (r *workspaceRepository) CountBrandsByTenant(ctx context.Context, tenantID int64) (int64, error) {
|
||||
return r.q.CountBrandsByTenant(ctx, tenantID)
|
||||
}
|
||||
|
||||
func (r *workspaceRepository) GetRecentArticles(ctx context.Context, tenantID int64) ([]WorkspaceRecentArticle, error) {
|
||||
rows, err := r.q.GetRecentArticles(ctx, tenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
articles := make([]WorkspaceRecentArticle, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
articles = append(articles, WorkspaceRecentArticle{
|
||||
ID: row.ID,
|
||||
GenerateStatus: row.GenerateStatus,
|
||||
PublishStatus: row.PublishStatus,
|
||||
SourceType: row.SourceType,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
Title: nullableText(row.Title),
|
||||
WordCount: intFromInt4(row.WordCount),
|
||||
SourceLabel: nullableText(row.SourceLabel),
|
||||
TemplateName: nullableText(row.TemplateName),
|
||||
})
|
||||
}
|
||||
|
||||
return articles, nil
|
||||
}
|
||||
|
||||
func (r *workspaceRepository) GetQuotaSummary(ctx context.Context, tenantID int64) (int, error) {
|
||||
balance, err := r.q.GetQuotaSummary(ctx, tenantID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(balance), nil
|
||||
}
|
||||
|
||||
func (r *workspaceRepository) GetActivePlanForTenant(ctx context.Context, tenantID int64) (*WorkspacePlan, error) {
|
||||
row, err := r.q.GetActivePlanForTenant(ctx, tenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &WorkspacePlan{
|
||||
PlanCode: row.PlanCode,
|
||||
PlanName: row.PlanName,
|
||||
QuotaPolicyJSON: row.QuotaPolicyJson,
|
||||
StartAt: timeFromTimestamp(row.StartAt),
|
||||
EndAt: timeFromTimestamp(row.EndAt),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user