feat(kol): marketplace and admin subscription repo queries
This commit is contained in:
@@ -15,7 +15,12 @@ const getPublishedKolPackage = `-- name: GetPublishedKolPackage :one
|
||||
SELECT kp.id, kp.tenant_id, kp.kol_profile_id, kp.name, kp.description,
|
||||
kp.cover_url, kp.industry, kp.tags, kp.price_note, kp.status,
|
||||
kp.created_at, kp.updated_at,
|
||||
pf.display_name AS kol_display_name, pf.avatar_url AS kol_avatar_url, pf.bio AS kol_bio
|
||||
pf.display_name AS kol_display_name, pf.avatar_url AS kol_avatar_url, pf.bio AS kol_bio,
|
||||
(SELECT COUNT(*) FROM kol_prompts p
|
||||
WHERE p.package_id = kp.id AND p.status = 'active' AND p.deleted_at IS NULL) AS prompt_count,
|
||||
(SELECT COUNT(*) FROM kol_subscriptions s
|
||||
WHERE s.package_id = kp.id AND s.status = 'active'
|
||||
AND (s.end_at IS NULL OR s.end_at > NOW())) AS subscriber_count
|
||||
FROM kol_packages kp
|
||||
JOIN kol_profiles pf ON pf.id = kp.kol_profile_id
|
||||
AND pf.status = 'active'
|
||||
@@ -27,21 +32,23 @@ WHERE kp.id = $1
|
||||
`
|
||||
|
||||
type GetPublishedKolPackageRow struct {
|
||||
ID int64 `json:"id"`
|
||||
TenantID int64 `json:"tenant_id"`
|
||||
KolProfileID int64 `json:"kol_profile_id"`
|
||||
Name string `json:"name"`
|
||||
Description pgtype.Text `json:"description"`
|
||||
CoverUrl pgtype.Text `json:"cover_url"`
|
||||
Industry pgtype.Text `json:"industry"`
|
||||
Tags []byte `json:"tags"`
|
||||
PriceNote pgtype.Text `json:"price_note"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
KolDisplayName string `json:"kol_display_name"`
|
||||
KolAvatarUrl pgtype.Text `json:"kol_avatar_url"`
|
||||
KolBio pgtype.Text `json:"kol_bio"`
|
||||
ID int64 `json:"id"`
|
||||
TenantID int64 `json:"tenant_id"`
|
||||
KolProfileID int64 `json:"kol_profile_id"`
|
||||
Name string `json:"name"`
|
||||
Description pgtype.Text `json:"description"`
|
||||
CoverUrl pgtype.Text `json:"cover_url"`
|
||||
Industry pgtype.Text `json:"industry"`
|
||||
Tags []byte `json:"tags"`
|
||||
PriceNote pgtype.Text `json:"price_note"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
||||
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
||||
KolDisplayName string `json:"kol_display_name"`
|
||||
KolAvatarUrl pgtype.Text `json:"kol_avatar_url"`
|
||||
KolBio pgtype.Text `json:"kol_bio"`
|
||||
PromptCount int64 `json:"prompt_count"`
|
||||
SubscriberCount int64 `json:"subscriber_count"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetPublishedKolPackage(ctx context.Context, id int64) (GetPublishedKolPackageRow, error) {
|
||||
@@ -63,6 +70,8 @@ func (q *Queries) GetPublishedKolPackage(ctx context.Context, id int64) (GetPubl
|
||||
&i.KolDisplayName,
|
||||
&i.KolAvatarUrl,
|
||||
&i.KolBio,
|
||||
&i.PromptCount,
|
||||
&i.SubscriberCount,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
@@ -151,6 +151,31 @@ func (q *Queries) GetKolSubscriptionByID(ctx context.Context, arg GetKolSubscrip
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getKolSubscriptionByIDAny = `-- name: GetKolSubscriptionByIDAny :one
|
||||
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
|
||||
FROM kol_subscriptions
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
// Cross-tenant read: V1 tenant-admin endpoints temporarily manage subscriptions here
|
||||
// until a dedicated platform-api exists.
|
||||
func (q *Queries) GetKolSubscriptionByIDAny(ctx context.Context, id int64) (KolSubscription, error) {
|
||||
row := q.db.QueryRow(ctx, getKolSubscriptionByIDAny, id)
|
||||
var i KolSubscription
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.TenantID,
|
||||
&i.PackageID,
|
||||
&i.Status,
|
||||
&i.ApprovedBy,
|
||||
&i.StartAt,
|
||||
&i.EndAt,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getSubscriptionPromptByID = `-- name: GetSubscriptionPromptByID :one
|
||||
SELECT sp.id, sp.tenant_id, sp.subscription_id, sp.package_id, sp.prompt_id,
|
||||
sp.status, sp.granted_at, sp.revoked_at,
|
||||
|
||||
@@ -62,6 +62,9 @@ type Querier interface {
|
||||
GetKolPromptByID(ctx context.Context, arg GetKolPromptByIDParams) (GetKolPromptByIDRow, error)
|
||||
GetKolPromptRevision(ctx context.Context, arg GetKolPromptRevisionParams) (GetKolPromptRevisionRow, error)
|
||||
GetKolSubscriptionByID(ctx context.Context, arg GetKolSubscriptionByIDParams) (KolSubscription, error)
|
||||
// Cross-tenant read: V1 tenant-admin endpoints temporarily manage subscriptions here
|
||||
// until a dedicated platform-api exists.
|
||||
GetKolSubscriptionByIDAny(ctx context.Context, id int64) (KolSubscription, error)
|
||||
GetKolUsageByGenerationTask(ctx context.Context, arg GetKolUsageByGenerationTaskParams) (GetKolUsageByGenerationTaskRow, error)
|
||||
GetPromptRuleByID(ctx context.Context, arg GetPromptRuleByIDParams) (GetPromptRuleByIDRow, error)
|
||||
GetPublishedKolPackage(ctx context.Context, id int64) (GetPublishedKolPackageRow, error)
|
||||
|
||||
@@ -107,21 +107,23 @@ func (r *kolMarketplaceRepository) GetPublished(ctx context.Context, id int64) (
|
||||
return nil, err
|
||||
}
|
||||
return &PublishedKolPackage{
|
||||
ID: row.ID,
|
||||
TenantID: row.TenantID,
|
||||
KolProfileID: row.KolProfileID,
|
||||
Name: row.Name,
|
||||
Description: nullableText(row.Description),
|
||||
CoverURL: nullableText(row.CoverUrl),
|
||||
Industry: nullableText(row.Industry),
|
||||
Tags: row.Tags,
|
||||
PriceNote: nullableText(row.PriceNote),
|
||||
Status: row.Status,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
|
||||
KolDisplayName: row.KolDisplayName,
|
||||
KolAvatarURL: nullableText(row.KolAvatarUrl),
|
||||
KolBio: nullableText(row.KolBio),
|
||||
ID: row.ID,
|
||||
TenantID: row.TenantID,
|
||||
KolProfileID: row.KolProfileID,
|
||||
Name: row.Name,
|
||||
Description: nullableText(row.Description),
|
||||
CoverURL: nullableText(row.CoverUrl),
|
||||
Industry: nullableText(row.Industry),
|
||||
Tags: row.Tags,
|
||||
PriceNote: nullableText(row.PriceNote),
|
||||
Status: row.Status,
|
||||
CreatedAt: timeFromTimestamp(row.CreatedAt),
|
||||
UpdatedAt: timeFromTimestamp(row.UpdatedAt),
|
||||
KolDisplayName: row.KolDisplayName,
|
||||
KolAvatarURL: nullableText(row.KolAvatarUrl),
|
||||
KolBio: nullableText(row.KolBio),
|
||||
PromptCount: row.PromptCount,
|
||||
SubscriberCount: row.SubscriberCount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ type CreateAccessRowInput struct {
|
||||
type KolSubscriptionRepository interface {
|
||||
Create(ctx context.Context, tenantID, packageID int64) (*KolSubscription, error)
|
||||
GetByID(ctx context.Context, tenantID, id int64) (*KolSubscription, error)
|
||||
GetByIDAny(ctx context.Context, id int64) (*KolSubscription, error)
|
||||
GetActiveForTenant(ctx context.Context, tenantID, packageID int64) (*KolSubscription, error)
|
||||
ListByTenant(ctx context.Context, tenantID int64) ([]KolSubscription, error)
|
||||
ListActiveSubscribersForPackage(ctx context.Context, packageID int64) ([]KolSubscription, error)
|
||||
@@ -117,6 +118,18 @@ func (r *kolSubscriptionRepository) GetByID(ctx context.Context, tenantID, id in
|
||||
return &sub, nil
|
||||
}
|
||||
|
||||
func (r *kolSubscriptionRepository) GetByIDAny(ctx context.Context, id int64) (*KolSubscription, error) {
|
||||
row, err := r.q.GetKolSubscriptionByIDAny(ctx, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
sub := mapKolSubscription(row)
|
||||
return &sub, nil
|
||||
}
|
||||
|
||||
func (r *kolSubscriptionRepository) GetActiveForTenant(ctx context.Context, tenantID, packageID int64) (*KolSubscription, error) {
|
||||
row, err := r.q.GetActiveKolSubscription(ctx, generated.GetActiveKolSubscriptionParams{
|
||||
TenantID: tenantID,
|
||||
|
||||
@@ -26,7 +26,12 @@ LIMIT sqlc.arg('limit') OFFSET sqlc.arg('offset');
|
||||
SELECT kp.id, kp.tenant_id, kp.kol_profile_id, kp.name, kp.description,
|
||||
kp.cover_url, kp.industry, kp.tags, kp.price_note, kp.status,
|
||||
kp.created_at, kp.updated_at,
|
||||
pf.display_name AS kol_display_name, pf.avatar_url AS kol_avatar_url, pf.bio AS kol_bio
|
||||
pf.display_name AS kol_display_name, pf.avatar_url AS kol_avatar_url, pf.bio AS kol_bio,
|
||||
(SELECT COUNT(*) FROM kol_prompts p
|
||||
WHERE p.package_id = kp.id AND p.status = 'active' AND p.deleted_at IS NULL) AS prompt_count,
|
||||
(SELECT COUNT(*) FROM kol_subscriptions s
|
||||
WHERE s.package_id = kp.id AND s.status = 'active'
|
||||
AND (s.end_at IS NULL OR s.end_at > NOW())) AS subscriber_count
|
||||
FROM kol_packages kp
|
||||
JOIN kol_profiles pf ON pf.id = kp.kol_profile_id
|
||||
AND pf.status = 'active'
|
||||
|
||||
@@ -9,6 +9,13 @@ FROM kol_subscriptions
|
||||
WHERE id = sqlc.arg(id)
|
||||
AND tenant_id = sqlc.arg(tenant_id)::bigint;
|
||||
|
||||
-- name: GetKolSubscriptionByIDAny :one
|
||||
-- Cross-tenant read: V1 tenant-admin endpoints temporarily manage subscriptions here
|
||||
-- until a dedicated platform-api exists.
|
||||
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
|
||||
FROM kol_subscriptions
|
||||
WHERE id = sqlc.arg(id);
|
||||
|
||||
-- name: GetActiveKolSubscription :one
|
||||
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
|
||||
FROM kol_subscriptions
|
||||
|
||||
Reference in New Issue
Block a user