79c65c1da7
- Add length/range limits to KOL variable definitions: max_length and default_value for input/textarea, min_value/max_value/default_number for number. Backend validates and normalizes; frontend renders limit inputs in KolVariableConfig and applies limits at runtime in KolDynamicForm. - Sort workspace cards by most recent prompt/package update, falling back to granted_at. Adds updated_at to KolWorkspaceCard. - Polish TemplatesView, WorkspaceView, and KOL package management UI; route create/update/publish/archive/delete toasts through i18n and expand package form copy and status labels. - Remove stale KnowledgeView.vue.patch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
142 lines
4.2 KiB
Go
142 lines
4.2 KiB
Go
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
|
|
GenerationMode *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 WorkspaceKolCard struct {
|
|
SubscriptionPromptID int64
|
|
GrantedAt time.Time
|
|
UpdatedAt time.Time
|
|
PromptName string
|
|
PlatformHint *string
|
|
PackageName string
|
|
PackageCover *string
|
|
KolDisplayName string
|
|
}
|
|
|
|
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)
|
|
ListKolCards(ctx context.Context, tenantID int64) ([]WorkspaceKolCard, 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,
|
|
GenerationMode: nullableAnyText(row.GenerationMode),
|
|
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
|
|
}
|
|
|
|
func (r *workspaceRepository) ListKolCards(ctx context.Context, tenantID int64) ([]WorkspaceKolCard, error) {
|
|
rows, err := r.q.ListKolCardsForTenant(ctx, tenantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
cards := make([]WorkspaceKolCard, 0, len(rows))
|
|
for _, row := range rows {
|
|
cards = append(cards, WorkspaceKolCard{
|
|
SubscriptionPromptID: row.SubscriptionPromptID,
|
|
GrantedAt: timeFromTimestamp(row.GrantedAt),
|
|
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
|
|
PromptName: row.PromptName,
|
|
PlatformHint: nullableText(row.PlatformHint),
|
|
PackageName: row.PackageName,
|
|
PackageCover: nullableText(row.PackageCover),
|
|
KolDisplayName: row.KolDisplayName,
|
|
})
|
|
}
|
|
|
|
return cards, nil
|
|
}
|