feat(kol): add sqlc queries for all KOL tables

This commit is contained in:
2026-04-17 08:10:45 +08:00
parent 5c8f2bffae
commit b78664c7d0
17 changed files with 2586 additions and 12 deletions
@@ -0,0 +1,134 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_assist.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const createKolAssistTask = `-- name: CreateKolAssistTask :exec
INSERT INTO kol_assist_tasks (id, tenant_id, kol_profile_id, prompt_id,
operator_id, task_type, status, request_json)
VALUES ($1, $2::bigint, $3,
$4, $5,
$6, 'queued', $7::jsonb)
`
type CreateKolAssistTaskParams struct {
ID string `json:"id"`
TenantID int64 `json:"tenant_id"`
KolProfileID int64 `json:"kol_profile_id"`
PromptID pgtype.Int8 `json:"prompt_id"`
OperatorID int64 `json:"operator_id"`
TaskType string `json:"task_type"`
RequestJson []byte `json:"request_json"`
}
func (q *Queries) CreateKolAssistTask(ctx context.Context, arg CreateKolAssistTaskParams) error {
_, err := q.db.Exec(ctx, createKolAssistTask,
arg.ID,
arg.TenantID,
arg.KolProfileID,
arg.PromptID,
arg.OperatorID,
arg.TaskType,
arg.RequestJson,
)
return err
}
const getKolAssistTask = `-- name: GetKolAssistTask :one
SELECT id, tenant_id, kol_profile_id, prompt_id, operator_id, task_type,
status, request_json, result_json, error_message,
started_at, completed_at, created_at, updated_at
FROM kol_assist_tasks
WHERE id = $1
AND tenant_id = $2::bigint
`
type GetKolAssistTaskParams struct {
ID string `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) GetKolAssistTask(ctx context.Context, arg GetKolAssistTaskParams) (KolAssistTask, error) {
row := q.db.QueryRow(ctx, getKolAssistTask, arg.ID, arg.TenantID)
var i KolAssistTask
err := row.Scan(
&i.ID,
&i.TenantID,
&i.KolProfileID,
&i.PromptID,
&i.OperatorID,
&i.TaskType,
&i.Status,
&i.RequestJson,
&i.ResultJson,
&i.ErrorMessage,
&i.StartedAt,
&i.CompletedAt,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const markKolAssistCompleted = `-- name: MarkKolAssistCompleted :exec
UPDATE kol_assist_tasks
SET status = 'completed', result_json = $1::jsonb,
completed_at = NOW(), updated_at = NOW()
WHERE id = $2
AND tenant_id = $3::bigint
`
type MarkKolAssistCompletedParams struct {
ResultJson []byte `json:"result_json"`
ID string `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolAssistCompleted(ctx context.Context, arg MarkKolAssistCompletedParams) error {
_, err := q.db.Exec(ctx, markKolAssistCompleted, arg.ResultJson, arg.ID, arg.TenantID)
return err
}
const markKolAssistFailed = `-- name: MarkKolAssistFailed :exec
UPDATE kol_assist_tasks
SET status = 'failed', error_message = $1,
completed_at = NOW(), updated_at = NOW()
WHERE id = $2
AND tenant_id = $3::bigint
`
type MarkKolAssistFailedParams struct {
ErrorMessage pgtype.Text `json:"error_message"`
ID string `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolAssistFailed(ctx context.Context, arg MarkKolAssistFailedParams) error {
_, err := q.db.Exec(ctx, markKolAssistFailed, arg.ErrorMessage, arg.ID, arg.TenantID)
return err
}
const markKolAssistStarted = `-- name: MarkKolAssistStarted :exec
UPDATE kol_assist_tasks
SET status = 'running', started_at = NOW(), updated_at = NOW()
WHERE id = $1
AND tenant_id = $2::bigint
`
type MarkKolAssistStartedParams struct {
ID string `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolAssistStarted(ctx context.Context, arg MarkKolAssistStartedParams) error {
_, err := q.db.Exec(ctx, markKolAssistStarted, arg.ID, arg.TenantID)
return err
}
@@ -0,0 +1,207 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_marketplace.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
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
FROM kol_packages kp
JOIN kol_profiles pf ON pf.id = kp.kol_profile_id
AND pf.status = 'active'
AND pf.market_enabled = TRUE
AND pf.deleted_at IS NULL
WHERE kp.id = $1
AND kp.status = 'published'
AND kp.deleted_at IS NULL
`
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"`
}
func (q *Queries) GetPublishedKolPackage(ctx context.Context, id int64) (GetPublishedKolPackageRow, error) {
row := q.db.QueryRow(ctx, getPublishedKolPackage, id)
var i GetPublishedKolPackageRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.KolProfileID,
&i.Name,
&i.Description,
&i.CoverUrl,
&i.Industry,
&i.Tags,
&i.PriceNote,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
&i.KolDisplayName,
&i.KolAvatarUrl,
&i.KolBio,
)
return i, err
}
const listPublicPromptsForPackage = `-- name: ListPublicPromptsForPackage :many
SELECT p.id, p.name, p.platform_hint, p.status,
p.published_revision_no, p.created_at
FROM kol_prompts p
WHERE p.package_id = $1
AND p.status = 'active'
AND p.published_revision_no IS NOT NULL
AND p.deleted_at IS NULL
ORDER BY p.sort_order ASC
`
type ListPublicPromptsForPackageRow struct {
ID int64 `json:"id"`
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
Status string `json:"status"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
func (q *Queries) ListPublicPromptsForPackage(ctx context.Context, packageID int64) ([]ListPublicPromptsForPackageRow, error) {
rows, err := q.db.Query(ctx, listPublicPromptsForPackage, packageID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListPublicPromptsForPackageRow
for rows.Next() {
var i ListPublicPromptsForPackageRow
if err := rows.Scan(
&i.ID,
&i.Name,
&i.PlatformHint,
&i.Status,
&i.PublishedRevisionNo,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPublishedKolPackages = `-- name: ListPublishedKolPackages :many
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,
(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') AS subscriber_count
FROM kol_packages kp
JOIN kol_profiles pf ON pf.id = kp.kol_profile_id
AND pf.status = 'active'
AND pf.market_enabled = TRUE
AND pf.deleted_at IS NULL
WHERE kp.status = 'published'
AND kp.deleted_at IS NULL
AND ($1::text IS NULL OR kp.industry = $1)
AND ($2::text IS NULL OR kp.name ILIKE '%' || $2 || '%')
ORDER BY kp.updated_at DESC
LIMIT $4 OFFSET $3
`
type ListPublishedKolPackagesParams struct {
Industry pgtype.Text `json:"industry"`
Keyword pgtype.Text `json:"keyword"`
Offset int32 `json:"offset"`
Limit int32 `json:"limit"`
}
type ListPublishedKolPackagesRow 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"`
PromptCount int64 `json:"prompt_count"`
SubscriberCount int64 `json:"subscriber_count"`
}
// Cross-tenant read: marketplace intentionally spans tenants.
// tenant_id appears via kol_profiles.tenant_id join only, so this file is exempt from check_tenant_scope.sh.
func (q *Queries) ListPublishedKolPackages(ctx context.Context, arg ListPublishedKolPackagesParams) ([]ListPublishedKolPackagesRow, error) {
rows, err := q.db.Query(ctx, listPublishedKolPackages,
arg.Industry,
arg.Keyword,
arg.Offset,
arg.Limit,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListPublishedKolPackagesRow
for rows.Next() {
var i ListPublishedKolPackagesRow
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.KolProfileID,
&i.Name,
&i.Description,
&i.CoverUrl,
&i.Industry,
&i.Tags,
&i.PriceNote,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
&i.KolDisplayName,
&i.KolAvatarUrl,
&i.PromptCount,
&i.SubscriberCount,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
@@ -0,0 +1,297 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_package.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const createKolPackage = `-- name: CreateKolPackage :one
INSERT INTO kol_packages (tenant_id, kol_profile_id, name, description, cover_url, industry, tags, price_note, status)
VALUES ($1::bigint, $2, $3,
$4, $5, $6,
$7::jsonb, $8, 'draft')
RETURNING id, tenant_id, kol_profile_id, name, description, cover_url,
industry, tags, price_note, status, created_at, updated_at
`
type CreateKolPackageParams struct {
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"`
}
type CreateKolPackageRow 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"`
}
func (q *Queries) CreateKolPackage(ctx context.Context, arg CreateKolPackageParams) (CreateKolPackageRow, error) {
row := q.db.QueryRow(ctx, createKolPackage,
arg.TenantID,
arg.KolProfileID,
arg.Name,
arg.Description,
arg.CoverUrl,
arg.Industry,
arg.Tags,
arg.PriceNote,
)
var i CreateKolPackageRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.KolProfileID,
&i.Name,
&i.Description,
&i.CoverUrl,
&i.Industry,
&i.Tags,
&i.PriceNote,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getKolPackageByID = `-- name: GetKolPackageByID :one
SELECT id, tenant_id, kol_profile_id, name, description, cover_url,
industry, tags, price_note, status, created_at, updated_at
FROM kol_packages
WHERE id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
`
type GetKolPackageByIDParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
type GetKolPackageByIDRow 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"`
}
func (q *Queries) GetKolPackageByID(ctx context.Context, arg GetKolPackageByIDParams) (GetKolPackageByIDRow, error) {
row := q.db.QueryRow(ctx, getKolPackageByID, arg.ID, arg.TenantID)
var i GetKolPackageByIDRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.KolProfileID,
&i.Name,
&i.Description,
&i.CoverUrl,
&i.Industry,
&i.Tags,
&i.PriceNote,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const listKolPackageIDsByProfile = `-- name: ListKolPackageIDsByProfile :many
SELECT id
FROM kol_packages
WHERE kol_profile_id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
`
type ListKolPackageIDsByProfileParams struct {
KolProfileID int64 `json:"kol_profile_id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) ListKolPackageIDsByProfile(ctx context.Context, arg ListKolPackageIDsByProfileParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listKolPackageIDsByProfile, arg.KolProfileID, arg.TenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listKolPackagesByProfile = `-- name: ListKolPackagesByProfile :many
SELECT id, tenant_id, kol_profile_id, name, description, cover_url,
industry, tags, price_note, status, created_at, updated_at
FROM kol_packages
WHERE kol_profile_id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
ORDER BY created_at DESC
`
type ListKolPackagesByProfileParams struct {
KolProfileID int64 `json:"kol_profile_id"`
TenantID int64 `json:"tenant_id"`
}
type ListKolPackagesByProfileRow 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"`
}
func (q *Queries) ListKolPackagesByProfile(ctx context.Context, arg ListKolPackagesByProfileParams) ([]ListKolPackagesByProfileRow, error) {
rows, err := q.db.Query(ctx, listKolPackagesByProfile, arg.KolProfileID, arg.TenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListKolPackagesByProfileRow
for rows.Next() {
var i ListKolPackagesByProfileRow
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.KolProfileID,
&i.Name,
&i.Description,
&i.CoverUrl,
&i.Industry,
&i.Tags,
&i.PriceNote,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const softDeleteKolPackage = `-- name: SoftDeleteKolPackage :exec
UPDATE kol_packages SET deleted_at = NOW()
WHERE id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
`
type SoftDeleteKolPackageParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) SoftDeleteKolPackage(ctx context.Context, arg SoftDeleteKolPackageParams) error {
_, err := q.db.Exec(ctx, softDeleteKolPackage, arg.ID, arg.TenantID)
return err
}
const updateKolPackage = `-- name: UpdateKolPackage :exec
UPDATE kol_packages
SET name = $1,
description = $2,
cover_url = $3,
industry = $4,
tags = $5::jsonb,
price_note = $6,
updated_at = NOW()
WHERE id = $7
AND tenant_id = $8::bigint
AND deleted_at IS NULL
`
type UpdateKolPackageParams struct {
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"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolPackage(ctx context.Context, arg UpdateKolPackageParams) error {
_, err := q.db.Exec(ctx, updateKolPackage,
arg.Name,
arg.Description,
arg.CoverUrl,
arg.Industry,
arg.Tags,
arg.PriceNote,
arg.ID,
arg.TenantID,
)
return err
}
const updateKolPackageStatus = `-- name: UpdateKolPackageStatus :exec
UPDATE kol_packages
SET status = $1,
updated_at = NOW()
WHERE id = $2
AND tenant_id = $3::bigint
AND deleted_at IS NULL
`
type UpdateKolPackageStatusParams struct {
Status string `json:"status"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolPackageStatus(ctx context.Context, arg UpdateKolPackageStatusParams) error {
_, err := q.db.Exec(ctx, updateKolPackageStatus, arg.Status, arg.ID, arg.TenantID)
return err
}
@@ -0,0 +1,125 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_profile.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const getKolProfileByID = `-- name: GetKolProfileByID :one
SELECT id, tenant_id, user_id, display_name, bio, avatar_url,
market_enabled, status, created_at, updated_at
FROM kol_profiles
WHERE id = $1 AND deleted_at IS NULL
`
type GetKolProfileByIDRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
DisplayName string `json:"display_name"`
Bio pgtype.Text `json:"bio"`
AvatarUrl pgtype.Text `json:"avatar_url"`
MarketEnabled bool `json:"market_enabled"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetKolProfileByID(ctx context.Context, id int64) (GetKolProfileByIDRow, error) {
row := q.db.QueryRow(ctx, getKolProfileByID, id)
var i GetKolProfileByIDRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.UserID,
&i.DisplayName,
&i.Bio,
&i.AvatarUrl,
&i.MarketEnabled,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getKolProfileByUser = `-- name: GetKolProfileByUser :one
SELECT id, tenant_id, user_id, display_name, bio, avatar_url,
market_enabled, status, created_at, updated_at
FROM kol_profiles
WHERE user_id = $1::bigint
AND tenant_id = $2::bigint
AND deleted_at IS NULL
`
type GetKolProfileByUserParams struct {
UserID int64 `json:"user_id"`
TenantID int64 `json:"tenant_id"`
}
type GetKolProfileByUserRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
DisplayName string `json:"display_name"`
Bio pgtype.Text `json:"bio"`
AvatarUrl pgtype.Text `json:"avatar_url"`
MarketEnabled bool `json:"market_enabled"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetKolProfileByUser(ctx context.Context, arg GetKolProfileByUserParams) (GetKolProfileByUserRow, error) {
row := q.db.QueryRow(ctx, getKolProfileByUser, arg.UserID, arg.TenantID)
var i GetKolProfileByUserRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.UserID,
&i.DisplayName,
&i.Bio,
&i.AvatarUrl,
&i.MarketEnabled,
&i.Status,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const updateKolProfile = `-- name: UpdateKolProfile :exec
UPDATE kol_profiles
SET display_name = $1,
bio = $2,
avatar_url = $3,
updated_at = NOW()
WHERE id = $4
AND tenant_id = $5::bigint
AND deleted_at IS NULL
`
type UpdateKolProfileParams struct {
DisplayName string `json:"display_name"`
Bio pgtype.Text `json:"bio"`
AvatarUrl pgtype.Text `json:"avatar_url"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolProfile(ctx context.Context, arg UpdateKolProfileParams) error {
_, err := q.db.Exec(ctx, updateKolProfile,
arg.DisplayName,
arg.Bio,
arg.AvatarUrl,
arg.ID,
arg.TenantID,
)
return err
}
@@ -0,0 +1,489 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_prompt.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const createKolPrompt = `-- name: CreateKolPrompt :one
INSERT INTO kol_prompts (tenant_id, package_id, name, platform_hint, sort_order, created_by, updated_by)
VALUES ($1::bigint, $2, $3,
$4, $5,
$6, $6)
RETURNING id, tenant_id, package_id, name, platform_hint, status, sort_order,
published_revision_no, draft_revision_no, created_by, updated_by,
created_at, updated_at
`
type CreateKolPromptParams struct {
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
SortOrder int32 `json:"sort_order"`
CreatedBy int64 `json:"created_by"`
}
type CreateKolPromptRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
Status string `json:"status"`
SortOrder int32 `json:"sort_order"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
DraftRevisionNo pgtype.Int4 `json:"draft_revision_no"`
CreatedBy int64 `json:"created_by"`
UpdatedBy int64 `json:"updated_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) CreateKolPrompt(ctx context.Context, arg CreateKolPromptParams) (CreateKolPromptRow, error) {
row := q.db.QueryRow(ctx, createKolPrompt,
arg.TenantID,
arg.PackageID,
arg.Name,
arg.PlatformHint,
arg.SortOrder,
arg.CreatedBy,
)
var i CreateKolPromptRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.Name,
&i.PlatformHint,
&i.Status,
&i.SortOrder,
&i.PublishedRevisionNo,
&i.DraftRevisionNo,
&i.CreatedBy,
&i.UpdatedBy,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const createKolPromptRevision = `-- name: CreateKolPromptRevision :one
INSERT INTO kol_prompt_revisions (tenant_id, prompt_id, revision_no, prompt_asset_key,
schema_json, card_config_json, created_by)
VALUES ($1::bigint, $2, $3,
$4, $5::jsonb,
$6::jsonb, $7)
RETURNING id, prompt_id, revision_no, prompt_asset_key, schema_json,
card_config_json, created_by, created_at
`
type CreateKolPromptRevisionParams struct {
TenantID int64 `json:"tenant_id"`
PromptID int64 `json:"prompt_id"`
RevisionNo int32 `json:"revision_no"`
PromptAssetKey string `json:"prompt_asset_key"`
SchemaJson []byte `json:"schema_json"`
CardConfigJson []byte `json:"card_config_json"`
CreatedBy int64 `json:"created_by"`
}
type CreateKolPromptRevisionRow struct {
ID int64 `json:"id"`
PromptID int64 `json:"prompt_id"`
RevisionNo int32 `json:"revision_no"`
PromptAssetKey string `json:"prompt_asset_key"`
SchemaJson []byte `json:"schema_json"`
CardConfigJson []byte `json:"card_config_json"`
CreatedBy int64 `json:"created_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
func (q *Queries) CreateKolPromptRevision(ctx context.Context, arg CreateKolPromptRevisionParams) (CreateKolPromptRevisionRow, error) {
row := q.db.QueryRow(ctx, createKolPromptRevision,
arg.TenantID,
arg.PromptID,
arg.RevisionNo,
arg.PromptAssetKey,
arg.SchemaJson,
arg.CardConfigJson,
arg.CreatedBy,
)
var i CreateKolPromptRevisionRow
err := row.Scan(
&i.ID,
&i.PromptID,
&i.RevisionNo,
&i.PromptAssetKey,
&i.SchemaJson,
&i.CardConfigJson,
&i.CreatedBy,
&i.CreatedAt,
)
return i, err
}
const getKolPromptByID = `-- name: GetKolPromptByID :one
SELECT id, tenant_id, package_id, name, platform_hint, status, sort_order,
published_revision_no, draft_revision_no, created_by, updated_by,
created_at, updated_at
FROM kol_prompts
WHERE id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
`
type GetKolPromptByIDParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
type GetKolPromptByIDRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
Status string `json:"status"`
SortOrder int32 `json:"sort_order"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
DraftRevisionNo pgtype.Int4 `json:"draft_revision_no"`
CreatedBy int64 `json:"created_by"`
UpdatedBy int64 `json:"updated_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) GetKolPromptByID(ctx context.Context, arg GetKolPromptByIDParams) (GetKolPromptByIDRow, error) {
row := q.db.QueryRow(ctx, getKolPromptByID, arg.ID, arg.TenantID)
var i GetKolPromptByIDRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.Name,
&i.PlatformHint,
&i.Status,
&i.SortOrder,
&i.PublishedRevisionNo,
&i.DraftRevisionNo,
&i.CreatedBy,
&i.UpdatedBy,
&i.CreatedAt,
&i.UpdatedAt,
)
return i, err
}
const getKolPromptRevision = `-- name: GetKolPromptRevision :one
SELECT id, prompt_id, revision_no, prompt_asset_key, schema_json,
card_config_json, created_by, created_at
FROM kol_prompt_revisions
WHERE prompt_id = $1
AND revision_no = $2
AND tenant_id = $3::bigint
`
type GetKolPromptRevisionParams struct {
PromptID int64 `json:"prompt_id"`
RevisionNo int32 `json:"revision_no"`
TenantID int64 `json:"tenant_id"`
}
type GetKolPromptRevisionRow struct {
ID int64 `json:"id"`
PromptID int64 `json:"prompt_id"`
RevisionNo int32 `json:"revision_no"`
PromptAssetKey string `json:"prompt_asset_key"`
SchemaJson []byte `json:"schema_json"`
CardConfigJson []byte `json:"card_config_json"`
CreatedBy int64 `json:"created_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
func (q *Queries) GetKolPromptRevision(ctx context.Context, arg GetKolPromptRevisionParams) (GetKolPromptRevisionRow, error) {
row := q.db.QueryRow(ctx, getKolPromptRevision, arg.PromptID, arg.RevisionNo, arg.TenantID)
var i GetKolPromptRevisionRow
err := row.Scan(
&i.ID,
&i.PromptID,
&i.RevisionNo,
&i.PromptAssetKey,
&i.SchemaJson,
&i.CardConfigJson,
&i.CreatedBy,
&i.CreatedAt,
)
return i, err
}
const listActiveKolPromptsByPackage = `-- name: ListActiveKolPromptsByPackage :many
SELECT id, tenant_id, package_id, published_revision_no
FROM kol_prompts
WHERE package_id = $1
AND tenant_id = $2::bigint
AND status = 'active'
AND published_revision_no IS NOT NULL
AND deleted_at IS NULL
ORDER BY sort_order ASC
`
type ListActiveKolPromptsByPackageParams struct {
PackageID int64 `json:"package_id"`
TenantID int64 `json:"tenant_id"`
}
type ListActiveKolPromptsByPackageRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
}
func (q *Queries) ListActiveKolPromptsByPackage(ctx context.Context, arg ListActiveKolPromptsByPackageParams) ([]ListActiveKolPromptsByPackageRow, error) {
rows, err := q.db.Query(ctx, listActiveKolPromptsByPackage, arg.PackageID, arg.TenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListActiveKolPromptsByPackageRow
for rows.Next() {
var i ListActiveKolPromptsByPackageRow
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.PublishedRevisionNo,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listKolPromptsByPackage = `-- name: ListKolPromptsByPackage :many
SELECT id, tenant_id, package_id, name, platform_hint, status, sort_order,
published_revision_no, draft_revision_no, created_by, updated_by,
created_at, updated_at
FROM kol_prompts
WHERE package_id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
ORDER BY sort_order ASC, created_at ASC
`
type ListKolPromptsByPackageParams struct {
PackageID int64 `json:"package_id"`
TenantID int64 `json:"tenant_id"`
}
type ListKolPromptsByPackageRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
Status string `json:"status"`
SortOrder int32 `json:"sort_order"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
DraftRevisionNo pgtype.Int4 `json:"draft_revision_no"`
CreatedBy int64 `json:"created_by"`
UpdatedBy int64 `json:"updated_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
func (q *Queries) ListKolPromptsByPackage(ctx context.Context, arg ListKolPromptsByPackageParams) ([]ListKolPromptsByPackageRow, error) {
rows, err := q.db.Query(ctx, listKolPromptsByPackage, arg.PackageID, arg.TenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListKolPromptsByPackageRow
for rows.Next() {
var i ListKolPromptsByPackageRow
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.Name,
&i.PlatformHint,
&i.Status,
&i.SortOrder,
&i.PublishedRevisionNo,
&i.DraftRevisionNo,
&i.CreatedBy,
&i.UpdatedBy,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const nextKolPromptRevisionNo = `-- name: NextKolPromptRevisionNo :one
SELECT COALESCE(MAX(revision_no), 0) + 1 AS next_revision_no
FROM kol_prompt_revisions
WHERE prompt_id = $1
AND tenant_id = $2::bigint
`
type NextKolPromptRevisionNoParams struct {
PromptID int64 `json:"prompt_id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) NextKolPromptRevisionNo(ctx context.Context, arg NextKolPromptRevisionNoParams) (int32, error) {
row := q.db.QueryRow(ctx, nextKolPromptRevisionNo, arg.PromptID, arg.TenantID)
var next_revision_no int32
err := row.Scan(&next_revision_no)
return next_revision_no, err
}
const softDeleteKolPrompt = `-- name: SoftDeleteKolPrompt :exec
UPDATE kol_prompts SET deleted_at = NOW()
WHERE id = $1
AND tenant_id = $2::bigint
AND deleted_at IS NULL
`
type SoftDeleteKolPromptParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) SoftDeleteKolPrompt(ctx context.Context, arg SoftDeleteKolPromptParams) error {
_, err := q.db.Exec(ctx, softDeleteKolPrompt, arg.ID, arg.TenantID)
return err
}
const updateKolPromptDraftRevision = `-- name: UpdateKolPromptDraftRevision :exec
UPDATE kol_prompts
SET draft_revision_no = $1,
updated_by = $2,
updated_at = NOW()
WHERE id = $3
AND tenant_id = $4::bigint
AND deleted_at IS NULL
`
type UpdateKolPromptDraftRevisionParams struct {
RevisionNo pgtype.Int4 `json:"revision_no"`
UpdatedBy int64 `json:"updated_by"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolPromptDraftRevision(ctx context.Context, arg UpdateKolPromptDraftRevisionParams) error {
_, err := q.db.Exec(ctx, updateKolPromptDraftRevision,
arg.RevisionNo,
arg.UpdatedBy,
arg.ID,
arg.TenantID,
)
return err
}
const updateKolPromptMetadata = `-- name: UpdateKolPromptMetadata :exec
UPDATE kol_prompts
SET name = $1,
platform_hint = $2,
sort_order = $3,
updated_by = $4,
updated_at = NOW()
WHERE id = $5
AND tenant_id = $6::bigint
AND deleted_at IS NULL
`
type UpdateKolPromptMetadataParams struct {
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
SortOrder int32 `json:"sort_order"`
UpdatedBy int64 `json:"updated_by"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolPromptMetadata(ctx context.Context, arg UpdateKolPromptMetadataParams) error {
_, err := q.db.Exec(ctx, updateKolPromptMetadata,
arg.Name,
arg.PlatformHint,
arg.SortOrder,
arg.UpdatedBy,
arg.ID,
arg.TenantID,
)
return err
}
const updateKolPromptPublishedRevision = `-- name: UpdateKolPromptPublishedRevision :exec
UPDATE kol_prompts
SET published_revision_no = $1,
status = 'active',
updated_by = $2,
updated_at = NOW()
WHERE id = $3
AND tenant_id = $4::bigint
AND deleted_at IS NULL
`
type UpdateKolPromptPublishedRevisionParams struct {
RevisionNo pgtype.Int4 `json:"revision_no"`
UpdatedBy int64 `json:"updated_by"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolPromptPublishedRevision(ctx context.Context, arg UpdateKolPromptPublishedRevisionParams) error {
_, err := q.db.Exec(ctx, updateKolPromptPublishedRevision,
arg.RevisionNo,
arg.UpdatedBy,
arg.ID,
arg.TenantID,
)
return err
}
const updateKolPromptStatus = `-- name: UpdateKolPromptStatus :exec
UPDATE kol_prompts
SET status = $1,
updated_by = $2,
updated_at = NOW()
WHERE id = $3
AND tenant_id = $4::bigint
AND deleted_at IS NULL
`
type UpdateKolPromptStatusParams struct {
Status string `json:"status"`
UpdatedBy int64 `json:"updated_by"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) UpdateKolPromptStatus(ctx context.Context, arg UpdateKolPromptStatusParams) error {
_, err := q.db.Exec(ctx, updateKolPromptStatus,
arg.Status,
arg.UpdatedBy,
arg.ID,
arg.TenantID,
)
return err
}
@@ -0,0 +1,401 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_subscription.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const approveKolSubscription = `-- name: ApproveKolSubscription :exec
UPDATE kol_subscriptions
SET status = 'active',
approved_by = $1,
start_at = NOW(),
end_at = $2,
updated_at = NOW()
WHERE id = $3
AND tenant_id = $4::bigint
`
type ApproveKolSubscriptionParams struct {
ApprovedBy pgtype.Int8 `json:"approved_by"`
EndAt pgtype.Timestamptz `json:"end_at"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) ApproveKolSubscription(ctx context.Context, arg ApproveKolSubscriptionParams) error {
_, err := q.db.Exec(ctx, approveKolSubscription,
arg.ApprovedBy,
arg.EndAt,
arg.ID,
arg.TenantID,
)
return err
}
const createKolSubscription = `-- name: CreateKolSubscription :one
INSERT INTO kol_subscriptions (tenant_id, package_id, status)
VALUES ($1::bigint, $2, 'pending')
RETURNING id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
`
type CreateKolSubscriptionParams struct {
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
}
func (q *Queries) CreateKolSubscription(ctx context.Context, arg CreateKolSubscriptionParams) (KolSubscription, error) {
row := q.db.QueryRow(ctx, createKolSubscription, arg.TenantID, arg.PackageID)
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 createSubscriptionPrompt = `-- name: CreateSubscriptionPrompt :exec
INSERT INTO kol_subscription_prompts (tenant_id, subscription_id, package_id, prompt_id, status)
VALUES ($1::bigint, $2,
$3, $4, 'active')
ON CONFLICT (subscription_id, prompt_id) DO NOTHING
`
type CreateSubscriptionPromptParams struct {
TenantID int64 `json:"tenant_id"`
SubscriptionID int64 `json:"subscription_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
}
func (q *Queries) CreateSubscriptionPrompt(ctx context.Context, arg CreateSubscriptionPromptParams) error {
_, err := q.db.Exec(ctx, createSubscriptionPrompt,
arg.TenantID,
arg.SubscriptionID,
arg.PackageID,
arg.PromptID,
)
return err
}
const getActiveKolSubscription = `-- name: GetActiveKolSubscription :one
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE tenant_id = $1::bigint
AND package_id = $2
AND status IN ('pending', 'active')
`
type GetActiveKolSubscriptionParams struct {
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
}
func (q *Queries) GetActiveKolSubscription(ctx context.Context, arg GetActiveKolSubscriptionParams) (KolSubscription, error) {
row := q.db.QueryRow(ctx, getActiveKolSubscription, arg.TenantID, arg.PackageID)
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 getKolSubscriptionByID = `-- name: GetKolSubscriptionByID :one
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE id = $1
AND tenant_id = $2::bigint
`
type GetKolSubscriptionByIDParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) GetKolSubscriptionByID(ctx context.Context, arg GetKolSubscriptionByIDParams) (KolSubscription, error) {
row := q.db.QueryRow(ctx, getKolSubscriptionByID, arg.ID, arg.TenantID)
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,
s.status AS subscription_status, s.end_at AS subscription_end_at,
p.name AS prompt_name, p.platform_hint, p.status AS prompt_status,
p.published_revision_no,
k.name AS package_name, k.status AS package_status
FROM kol_subscription_prompts sp
JOIN kol_subscriptions s ON s.id = sp.subscription_id
JOIN kol_prompts p ON p.id = sp.prompt_id AND p.deleted_at IS NULL
JOIN kol_packages k ON k.id = sp.package_id AND k.deleted_at IS NULL
WHERE sp.id = $1
AND sp.tenant_id = $2::bigint
`
type GetSubscriptionPromptByIDParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
type GetSubscriptionPromptByIDRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
SubscriptionID int64 `json:"subscription_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
Status string `json:"status"`
GrantedAt pgtype.Timestamptz `json:"granted_at"`
RevokedAt pgtype.Timestamptz `json:"revoked_at"`
SubscriptionStatus string `json:"subscription_status"`
SubscriptionEndAt pgtype.Timestamptz `json:"subscription_end_at"`
PromptName string `json:"prompt_name"`
PlatformHint pgtype.Text `json:"platform_hint"`
PromptStatus string `json:"prompt_status"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
PackageName string `json:"package_name"`
PackageStatus string `json:"package_status"`
}
func (q *Queries) GetSubscriptionPromptByID(ctx context.Context, arg GetSubscriptionPromptByIDParams) (GetSubscriptionPromptByIDRow, error) {
row := q.db.QueryRow(ctx, getSubscriptionPromptByID, arg.ID, arg.TenantID)
var i GetSubscriptionPromptByIDRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.SubscriptionID,
&i.PackageID,
&i.PromptID,
&i.Status,
&i.GrantedAt,
&i.RevokedAt,
&i.SubscriptionStatus,
&i.SubscriptionEndAt,
&i.PromptName,
&i.PlatformHint,
&i.PromptStatus,
&i.PublishedRevisionNo,
&i.PackageName,
&i.PackageStatus,
)
return i, err
}
const listActiveSubscribersForPackage = `-- name: ListActiveSubscribersForPackage :many
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE package_id = $1
AND tenant_id IS NOT NULL
AND status = 'active'
`
func (q *Queries) ListActiveSubscribersForPackage(ctx context.Context, packageID int64) ([]KolSubscription, error) {
rows, err := q.db.Query(ctx, listActiveSubscribersForPackage, packageID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []KolSubscription
for rows.Next() {
var i KolSubscription
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.Status,
&i.ApprovedBy,
&i.StartAt,
&i.EndAt,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listKolSubscriptions = `-- name: ListKolSubscriptions :many
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE tenant_id = $1::bigint
ORDER BY created_at DESC
`
func (q *Queries) ListKolSubscriptions(ctx context.Context, tenantID int64) ([]KolSubscription, error) {
rows, err := q.db.Query(ctx, listKolSubscriptions, tenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []KolSubscription
for rows.Next() {
var i KolSubscription
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.Status,
&i.ApprovedBy,
&i.StartAt,
&i.EndAt,
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listSubscriptionPromptsByTenant = `-- name: ListSubscriptionPromptsByTenant :many
SELECT sp.id, sp.tenant_id, sp.subscription_id, sp.package_id, sp.prompt_id,
sp.status, sp.granted_at, sp.revoked_at,
p.name AS prompt_name, p.platform_hint, p.published_revision_no,
k.name AS package_name
FROM kol_subscription_prompts sp
JOIN kol_prompts p ON p.id = sp.prompt_id AND p.deleted_at IS NULL
JOIN kol_packages k ON k.id = sp.package_id AND k.deleted_at IS NULL
WHERE sp.tenant_id = $1::bigint
AND sp.status = 'active'
ORDER BY sp.granted_at DESC
`
type ListSubscriptionPromptsByTenantRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
SubscriptionID int64 `json:"subscription_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
Status string `json:"status"`
GrantedAt pgtype.Timestamptz `json:"granted_at"`
RevokedAt pgtype.Timestamptz `json:"revoked_at"`
PromptName string `json:"prompt_name"`
PlatformHint pgtype.Text `json:"platform_hint"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
PackageName string `json:"package_name"`
}
func (q *Queries) ListSubscriptionPromptsByTenant(ctx context.Context, tenantID int64) ([]ListSubscriptionPromptsByTenantRow, error) {
rows, err := q.db.Query(ctx, listSubscriptionPromptsByTenant, tenantID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListSubscriptionPromptsByTenantRow
for rows.Next() {
var i ListSubscriptionPromptsByTenantRow
if err := rows.Scan(
&i.ID,
&i.TenantID,
&i.SubscriptionID,
&i.PackageID,
&i.PromptID,
&i.Status,
&i.GrantedAt,
&i.RevokedAt,
&i.PromptName,
&i.PlatformHint,
&i.PublishedRevisionNo,
&i.PackageName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const revokeKolSubscription = `-- name: RevokeKolSubscription :exec
UPDATE kol_subscriptions
SET status = 'revoked', updated_at = NOW()
WHERE id = $1
AND tenant_id = $2::bigint
`
type RevokeKolSubscriptionParams struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) RevokeKolSubscription(ctx context.Context, arg RevokeKolSubscriptionParams) error {
_, err := q.db.Exec(ctx, revokeKolSubscription, arg.ID, arg.TenantID)
return err
}
const revokeSubscriptionPromptsByPrompt = `-- name: RevokeSubscriptionPromptsByPrompt :exec
UPDATE kol_subscription_prompts
SET status = 'revoked', revoked_at = NOW(), updated_at = NOW()
WHERE prompt_id = $1
AND tenant_id = $2::bigint
`
type RevokeSubscriptionPromptsByPromptParams struct {
PromptID int64 `json:"prompt_id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) RevokeSubscriptionPromptsByPrompt(ctx context.Context, arg RevokeSubscriptionPromptsByPromptParams) error {
_, err := q.db.Exec(ctx, revokeSubscriptionPromptsByPrompt, arg.PromptID, arg.TenantID)
return err
}
const revokeSubscriptionPromptsBySubscription = `-- name: RevokeSubscriptionPromptsBySubscription :exec
UPDATE kol_subscription_prompts
SET status = 'revoked', revoked_at = NOW(), updated_at = NOW()
WHERE subscription_id = $1
AND tenant_id = $2::bigint
`
type RevokeSubscriptionPromptsBySubscriptionParams struct {
SubscriptionID int64 `json:"subscription_id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) RevokeSubscriptionPromptsBySubscription(ctx context.Context, arg RevokeSubscriptionPromptsBySubscriptionParams) error {
_, err := q.db.Exec(ctx, revokeSubscriptionPromptsBySubscription, arg.SubscriptionID, arg.TenantID)
return err
}
@@ -0,0 +1,306 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.30.0
// source: kol_usage.sql
package generated
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const createKolUsageLog = `-- name: CreateKolUsageLog :one
INSERT INTO kol_usage_logs (tenant_id, subscription_id, subscription_prompt_id,
package_id, prompt_id, prompt_revision_no,
generation_task_id, status, variables_snapshot,
schema_snapshot, rendered_prompt_hash)
VALUES ($1::bigint, $2,
$3, $4,
$5, $6,
$7, 'pending',
$8::jsonb, $9::jsonb,
$10)
RETURNING id, tenant_id, generation_task_id, status, created_at
`
type CreateKolUsageLogParams struct {
TenantID int64 `json:"tenant_id"`
SubscriptionID pgtype.Int8 `json:"subscription_id"`
SubscriptionPromptID pgtype.Int8 `json:"subscription_prompt_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
PromptRevisionNo int32 `json:"prompt_revision_no"`
GenerationTaskID pgtype.Int8 `json:"generation_task_id"`
VariablesSnapshot []byte `json:"variables_snapshot"`
SchemaSnapshot []byte `json:"schema_snapshot"`
RenderedPromptHash pgtype.Text `json:"rendered_prompt_hash"`
}
type CreateKolUsageLogRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
GenerationTaskID pgtype.Int8 `json:"generation_task_id"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
func (q *Queries) CreateKolUsageLog(ctx context.Context, arg CreateKolUsageLogParams) (CreateKolUsageLogRow, error) {
row := q.db.QueryRow(ctx, createKolUsageLog,
arg.TenantID,
arg.SubscriptionID,
arg.SubscriptionPromptID,
arg.PackageID,
arg.PromptID,
arg.PromptRevisionNo,
arg.GenerationTaskID,
arg.VariablesSnapshot,
arg.SchemaSnapshot,
arg.RenderedPromptHash,
)
var i CreateKolUsageLogRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.GenerationTaskID,
&i.Status,
&i.CreatedAt,
)
return i, err
}
const getKolUsageByGenerationTask = `-- name: GetKolUsageByGenerationTask :one
SELECT id, tenant_id, package_id, prompt_id, status, created_at
FROM kol_usage_logs
WHERE generation_task_id = $1
AND tenant_id = $2::bigint
`
type GetKolUsageByGenerationTaskParams struct {
GenerationTaskID pgtype.Int8 `json:"generation_task_id"`
TenantID int64 `json:"tenant_id"`
}
type GetKolUsageByGenerationTaskRow struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
func (q *Queries) GetKolUsageByGenerationTask(ctx context.Context, arg GetKolUsageByGenerationTaskParams) (GetKolUsageByGenerationTaskRow, error) {
row := q.db.QueryRow(ctx, getKolUsageByGenerationTask, arg.GenerationTaskID, arg.TenantID)
var i GetKolUsageByGenerationTaskRow
err := row.Scan(
&i.ID,
&i.TenantID,
&i.PackageID,
&i.PromptID,
&i.Status,
&i.CreatedAt,
)
return i, err
}
const kolDashboardOverview = `-- name: KolDashboardOverview :one
SELECT
(SELECT COUNT(DISTINCT s.tenant_id) FROM kol_subscriptions s
WHERE s.package_id = ANY($1::bigint[]) AND s.status='active'
AND (s.end_at IS NULL OR s.end_at > NOW())) AS total_subs,
(SELECT COUNT(*) FROM kol_subscriptions s
WHERE s.package_id = ANY($1::bigint[])
AND s.status='active'
AND s.created_at >= date_trunc('month', NOW())) AS month_subs,
(SELECT COUNT(*) FROM kol_usage_logs u
WHERE u.package_id = ANY($1::bigint[])
AND u.tenant_id IS NOT NULL) AS total_usage,
(SELECT COUNT(*) FROM kol_usage_logs u
WHERE u.package_id = ANY($1::bigint[])
AND u.tenant_id IS NOT NULL
AND u.created_at >= date_trunc('month', NOW())) AS month_usage,
(SELECT COUNT(*) FROM kol_usage_logs u
WHERE u.package_id = ANY($1::bigint[])
AND u.tenant_id IS NOT NULL
AND u.status='failed') AS failure_count
`
type KolDashboardOverviewRow struct {
TotalSubs int64 `json:"total_subs"`
MonthSubs int64 `json:"month_subs"`
TotalUsage int64 `json:"total_usage"`
MonthUsage int64 `json:"month_usage"`
FailureCount int64 `json:"failure_count"`
}
func (q *Queries) KolDashboardOverview(ctx context.Context, packageIds []int64) (KolDashboardOverviewRow, error) {
row := q.db.QueryRow(ctx, kolDashboardOverview, packageIds)
var i KolDashboardOverviewRow
err := row.Scan(
&i.TotalSubs,
&i.MonthSubs,
&i.TotalUsage,
&i.MonthUsage,
&i.FailureCount,
)
return i, err
}
const kolDashboardTrend = `-- name: KolDashboardTrend :many
SELECT date_trunc('day', u.created_at)::date AS d,
COUNT(*) FILTER (WHERE u.status='completed') AS usages
FROM kol_usage_logs u
WHERE u.package_id = ANY($1::bigint[])
AND u.tenant_id IS NOT NULL
AND u.created_at >= NOW() - $2::int * INTERVAL '1 day'
GROUP BY d
ORDER BY d ASC
`
type KolDashboardTrendParams struct {
PackageIds []int64 `json:"package_ids"`
PeriodDays int32 `json:"period_days"`
}
type KolDashboardTrendRow struct {
D pgtype.Date `json:"d"`
Usages int64 `json:"usages"`
}
func (q *Queries) KolDashboardTrend(ctx context.Context, arg KolDashboardTrendParams) ([]KolDashboardTrendRow, error) {
rows, err := q.db.Query(ctx, kolDashboardTrend, arg.PackageIds, arg.PeriodDays)
if err != nil {
return nil, err
}
defer rows.Close()
var items []KolDashboardTrendRow
for rows.Next() {
var i KolDashboardTrendRow
if err := rows.Scan(&i.D, &i.Usages); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const kolUsageCountByPackage = `-- name: KolUsageCountByPackage :many
SELECT package_id, COUNT(*) AS total,
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed,
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed
FROM kol_usage_logs
WHERE package_id = ANY($1::bigint[])
AND tenant_id IS NOT NULL
GROUP BY package_id
`
type KolUsageCountByPackageRow struct {
PackageID int64 `json:"package_id"`
Total int64 `json:"total"`
Completed int64 `json:"completed"`
Failed int64 `json:"failed"`
}
func (q *Queries) KolUsageCountByPackage(ctx context.Context, packageIds []int64) ([]KolUsageCountByPackageRow, error) {
rows, err := q.db.Query(ctx, kolUsageCountByPackage, packageIds)
if err != nil {
return nil, err
}
defer rows.Close()
var items []KolUsageCountByPackageRow
for rows.Next() {
var i KolUsageCountByPackageRow
if err := rows.Scan(
&i.PackageID,
&i.Total,
&i.Completed,
&i.Failed,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const markKolUsageCompleted = `-- name: MarkKolUsageCompleted :exec
UPDATE kol_usage_logs
SET status = 'completed', article_id = $1,
finished_at = NOW()
WHERE id = $2
AND tenant_id = $3::bigint
`
type MarkKolUsageCompletedParams struct {
ArticleID pgtype.Int8 `json:"article_id"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolUsageCompleted(ctx context.Context, arg MarkKolUsageCompletedParams) error {
_, err := q.db.Exec(ctx, markKolUsageCompleted, arg.ArticleID, arg.ID, arg.TenantID)
return err
}
const markKolUsageCompletedByTask = `-- name: MarkKolUsageCompletedByTask :exec
UPDATE kol_usage_logs
SET status = 'completed', article_id = $1, finished_at = NOW()
WHERE generation_task_id = $2
AND tenant_id = $3::bigint
`
type MarkKolUsageCompletedByTaskParams struct {
ArticleID pgtype.Int8 `json:"article_id"`
GenerationTaskID pgtype.Int8 `json:"generation_task_id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolUsageCompletedByTask(ctx context.Context, arg MarkKolUsageCompletedByTaskParams) error {
_, err := q.db.Exec(ctx, markKolUsageCompletedByTask, arg.ArticleID, arg.GenerationTaskID, arg.TenantID)
return err
}
const markKolUsageFailed = `-- name: MarkKolUsageFailed :exec
UPDATE kol_usage_logs
SET status = 'failed', error_message = $1,
finished_at = NOW()
WHERE id = $2
AND tenant_id = $3::bigint
`
type MarkKolUsageFailedParams struct {
ErrorMessage pgtype.Text `json:"error_message"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolUsageFailed(ctx context.Context, arg MarkKolUsageFailedParams) error {
_, err := q.db.Exec(ctx, markKolUsageFailed, arg.ErrorMessage, arg.ID, arg.TenantID)
return err
}
const markKolUsageFailedByTask = `-- name: MarkKolUsageFailedByTask :exec
UPDATE kol_usage_logs
SET status = 'failed', error_message = $1, finished_at = NOW()
WHERE generation_task_id = $2
AND tenant_id = $3::bigint
`
type MarkKolUsageFailedByTaskParams struct {
ErrorMessage pgtype.Text `json:"error_message"`
GenerationTaskID pgtype.Int8 `json:"generation_task_id"`
TenantID int64 `json:"tenant_id"`
}
func (q *Queries) MarkKolUsageFailedByTask(ctx context.Context, arg MarkKolUsageFailedByTaskParams) error {
_, err := q.db.Exec(ctx, markKolUsageFailedByTask, arg.ErrorMessage, arg.GenerationTaskID, arg.TenantID)
return err
}
@@ -21,6 +21,7 @@ type Article struct {
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
WizardStateJson []byte `json:"wizard_state_json"`
KolPromptID pgtype.Int8 `json:"kol_prompt_id"`
}
type ArticleTemplate struct {
@@ -137,17 +138,18 @@ type GenerationTask struct {
}
type ImageAsset struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
FolderID pgtype.Int8 `json:"folder_id"`
ObjectKey string `json:"object_key"`
Name string `json:"name"`
SizeBytes int64 `json:"size_bytes"`
Status string `json:"status"`
CreatedBy int64 `json:"created_by"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
FolderID pgtype.Int8 `json:"folder_id"`
ObjectKey string `json:"object_key"`
Name string `json:"name"`
SizeBytes int64 `json:"size_bytes"`
Status string `json:"status"`
CreatedBy int64 `json:"created_by"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
ContentHash pgtype.Text `json:"content_hash"`
}
type ImageAssetReference struct {
@@ -224,6 +226,126 @@ type KnowledgeParseTask struct {
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type KolAssistTask struct {
ID string `json:"id"`
TenantID int64 `json:"tenant_id"`
KolProfileID int64 `json:"kol_profile_id"`
PromptID pgtype.Int8 `json:"prompt_id"`
OperatorID int64 `json:"operator_id"`
TaskType string `json:"task_type"`
Status string `json:"status"`
RequestJson []byte `json:"request_json"`
ResultJson []byte `json:"result_json"`
ErrorMessage pgtype.Text `json:"error_message"`
StartedAt pgtype.Timestamptz `json:"started_at"`
CompletedAt pgtype.Timestamptz `json:"completed_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type KolPackage 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"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
}
type KolProfile struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
UserID int64 `json:"user_id"`
DisplayName string `json:"display_name"`
Bio pgtype.Text `json:"bio"`
AvatarUrl pgtype.Text `json:"avatar_url"`
MarketEnabled bool `json:"market_enabled"`
Status string `json:"status"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
}
type KolPrompt struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
Name string `json:"name"`
PlatformHint pgtype.Text `json:"platform_hint"`
Status string `json:"status"`
SortOrder int32 `json:"sort_order"`
PublishedRevisionNo pgtype.Int4 `json:"published_revision_no"`
DraftRevisionNo pgtype.Int4 `json:"draft_revision_no"`
CreatedBy int64 `json:"created_by"`
UpdatedBy int64 `json:"updated_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
DeletedAt pgtype.Timestamptz `json:"deleted_at"`
}
type KolPromptRevision struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PromptID int64 `json:"prompt_id"`
RevisionNo int32 `json:"revision_no"`
PromptAssetKey string `json:"prompt_asset_key"`
SchemaJson []byte `json:"schema_json"`
CardConfigJson []byte `json:"card_config_json"`
CreatedBy int64 `json:"created_by"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
}
type KolSubscription struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
PackageID int64 `json:"package_id"`
Status string `json:"status"`
ApprovedBy pgtype.Int8 `json:"approved_by"`
StartAt pgtype.Timestamptz `json:"start_at"`
EndAt pgtype.Timestamptz `json:"end_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type KolSubscriptionPrompt struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
SubscriptionID int64 `json:"subscription_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
Status string `json:"status"`
GrantedAt pgtype.Timestamptz `json:"granted_at"`
RevokedAt pgtype.Timestamptz `json:"revoked_at"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
}
type KolUsageLog struct {
ID int64 `json:"id"`
TenantID int64 `json:"tenant_id"`
SubscriptionID pgtype.Int8 `json:"subscription_id"`
SubscriptionPromptID pgtype.Int8 `json:"subscription_prompt_id"`
PackageID int64 `json:"package_id"`
PromptID int64 `json:"prompt_id"`
PromptRevisionNo int32 `json:"prompt_revision_no"`
ArticleID pgtype.Int8 `json:"article_id"`
GenerationTaskID pgtype.Int8 `json:"generation_task_id"`
Status string `json:"status"`
VariablesSnapshot []byte `json:"variables_snapshot"`
SchemaSnapshot []byte `json:"schema_snapshot"`
RenderedPromptHash pgtype.Text `json:"rendered_prompt_hash"`
ErrorMessage pgtype.Text `json:"error_message"`
CreatedAt pgtype.Timestamptz `json:"created_at"`
FinishedAt pgtype.Timestamptz `json:"finished_at"`
}
type MediaPlatform struct {
ID int64 `json:"id"`
PlatformID string `json:"platform_id"`
@@ -9,6 +9,7 @@ import (
)
type Querier interface {
ApproveKolSubscription(ctx context.Context, arg ApproveKolSubscriptionParams) error
ConfirmReservation(ctx context.Context, arg ConfirmReservationParams) error
CountActiveImagesInFolder(ctx context.Context, arg CountActiveImagesInFolderParams) (int32, error)
CountArticles(ctx context.Context, arg CountArticlesParams) (int64, error)
@@ -29,15 +30,23 @@ type Querier interface {
CreateGenerationTask(ctx context.Context, arg CreateGenerationTaskParams) (int64, error)
CreateImageFolder(ctx context.Context, arg CreateImageFolderParams) (int64, error)
CreateKeyword(ctx context.Context, arg CreateKeywordParams) (CreateKeywordRow, error)
CreateKolAssistTask(ctx context.Context, arg CreateKolAssistTaskParams) error
CreateKolPackage(ctx context.Context, arg CreateKolPackageParams) (CreateKolPackageRow, error)
CreateKolPrompt(ctx context.Context, arg CreateKolPromptParams) (CreateKolPromptRow, error)
CreateKolPromptRevision(ctx context.Context, arg CreateKolPromptRevisionParams) (CreateKolPromptRevisionRow, error)
CreateKolSubscription(ctx context.Context, arg CreateKolSubscriptionParams) (KolSubscription, error)
CreateKolUsageLog(ctx context.Context, arg CreateKolUsageLogParams) (CreateKolUsageLogRow, error)
CreatePromptRule(ctx context.Context, arg CreatePromptRuleParams) (CreatePromptRuleRow, error)
CreatePromptRuleGroup(ctx context.Context, arg CreatePromptRuleGroupParams) (CreatePromptRuleGroupRow, error)
CreateQuestion(ctx context.Context, arg CreateQuestionParams) (int64, error)
CreateQuotaReservation(ctx context.Context, arg CreateQuotaReservationParams) (int64, error)
CreateScheduleTask(ctx context.Context, arg CreateScheduleTaskParams) (CreateScheduleTaskRow, error)
CreateSubscriptionPrompt(ctx context.Context, arg CreateSubscriptionPromptParams) error
DeleteImageFolder(ctx context.Context, arg DeleteImageFolderParams) error
DeleteImageReferencesByArticle(ctx context.Context, arg DeleteImageReferencesByArticleParams) error
DeleteImageReferencesByArticleScope(ctx context.Context, arg DeleteImageReferencesByArticleScopeParams) error
EnsureImageStorageUsageRow(ctx context.Context, tenantID int64) error
GetActiveKolSubscription(ctx context.Context, arg GetActiveKolSubscriptionParams) (KolSubscription, error)
GetActivePlanForTenant(ctx context.Context, tenantID int64) (GetActivePlanForTenantRow, error)
GetArticleByID(ctx context.Context, arg GetArticleByIDParams) (GetArticleByIDRow, error)
GetArticleVersions(ctx context.Context, articleID int64) ([]GetArticleVersionsRow, error)
@@ -46,10 +55,20 @@ type Querier interface {
GetImageAsset(ctx context.Context, arg GetImageAssetParams) (GetImageAssetRow, error)
GetImageFolder(ctx context.Context, arg GetImageFolderParams) (GetImageFolderRow, error)
GetImageStorageUsage(ctx context.Context, tenantID int64) (GetImageStorageUsageRow, error)
GetKolAssistTask(ctx context.Context, arg GetKolAssistTaskParams) (KolAssistTask, error)
GetKolPackageByID(ctx context.Context, arg GetKolPackageByIDParams) (GetKolPackageByIDRow, error)
GetKolProfileByID(ctx context.Context, id int64) (GetKolProfileByIDRow, error)
GetKolProfileByUser(ctx context.Context, arg GetKolProfileByUserParams) (GetKolProfileByUserRow, error)
GetKolPromptByID(ctx context.Context, arg GetKolPromptByIDParams) (GetKolPromptByIDRow, error)
GetKolPromptRevision(ctx context.Context, arg GetKolPromptRevisionParams) (GetKolPromptRevisionRow, error)
GetKolSubscriptionByID(ctx context.Context, arg GetKolSubscriptionByIDParams) (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)
GetQuotaSummary(ctx context.Context, tenantID int64) (int32, error)
GetRecentArticles(ctx context.Context, tenantID int64) ([]GetRecentArticlesRow, error)
GetScheduleTaskByID(ctx context.Context, arg GetScheduleTaskByIDParams) (GetScheduleTaskByIDRow, error)
GetSubscriptionPromptByID(ctx context.Context, arg GetSubscriptionPromptByIDParams) (GetSubscriptionPromptByIDRow, error)
GetTemplateByID(ctx context.Context, arg GetTemplateByIDParams) (GetTemplateByIDRow, error)
GetTenantMembership(ctx context.Context, userID int64) (GetTenantMembershipRow, error)
GetTenantMembershipByTenantAndUser(ctx context.Context, arg GetTenantMembershipByTenantAndUserParams) (GetTenantMembershipByTenantAndUserRow, error)
@@ -57,7 +76,12 @@ type Querier interface {
GetUserByID(ctx context.Context, id int64) (GetUserByIDRow, error)
InsertImageAsset(ctx context.Context, arg InsertImageAssetParams) (int64, error)
InsertQuotaLedger(ctx context.Context, arg InsertQuotaLedgerParams) (int64, error)
KolDashboardOverview(ctx context.Context, packageIds []int64) (KolDashboardOverviewRow, error)
KolDashboardTrend(ctx context.Context, arg KolDashboardTrendParams) ([]KolDashboardTrendRow, error)
KolUsageCountByPackage(ctx context.Context, packageIds []int64) ([]KolUsageCountByPackageRow, error)
ListActiveImagesByFolder(ctx context.Context, arg ListActiveImagesByFolderParams) ([]ListActiveImagesByFolderRow, error)
ListActiveKolPromptsByPackage(ctx context.Context, arg ListActiveKolPromptsByPackageParams) ([]ListActiveKolPromptsByPackageRow, error)
ListActiveSubscribersForPackage(ctx context.Context, packageID int64) ([]KolSubscription, error)
ListAllPromptRulesSimple(ctx context.Context, tenantID int64) ([]ListAllPromptRulesSimpleRow, error)
ListArticles(ctx context.Context, arg ListArticlesParams) ([]ListArticlesRow, error)
ListBrands(ctx context.Context, tenantID int64) ([]ListBrandsRow, error)
@@ -67,6 +91,10 @@ type Querier interface {
ListImageReferenceArticles(ctx context.Context, arg ListImageReferenceArticlesParams) ([]ListImageReferenceArticlesRow, error)
ListImageReferences(ctx context.Context, arg ListImageReferencesParams) ([]ListImageReferencesRow, error)
ListKeywords(ctx context.Context, arg ListKeywordsParams) ([]ListKeywordsRow, error)
ListKolPackageIDsByProfile(ctx context.Context, arg ListKolPackageIDsByProfileParams) ([]int64, error)
ListKolPackagesByProfile(ctx context.Context, arg ListKolPackagesByProfileParams) ([]ListKolPackagesByProfileRow, error)
ListKolPromptsByPackage(ctx context.Context, arg ListKolPromptsByPackageParams) ([]ListKolPromptsByPackageRow, error)
ListKolSubscriptions(ctx context.Context, tenantID int64) ([]KolSubscription, error)
// ============================================================
// Prompt Rule Groups
// ============================================================
@@ -76,18 +104,36 @@ type Querier interface {
// ============================================================
ListPromptRules(ctx context.Context, arg ListPromptRulesParams) ([]ListPromptRulesRow, error)
ListPromptRulesUngrouped(ctx context.Context, arg ListPromptRulesUngroupedParams) ([]ListPromptRulesUngroupedRow, error)
ListPublicPromptsForPackage(ctx context.Context, packageID int64) ([]ListPublicPromptsForPackageRow, error)
// Cross-tenant read: marketplace intentionally spans tenants.
// tenant_id appears via kol_profiles.tenant_id join only, so this file is exempt from check_tenant_scope.sh.
ListPublishedKolPackages(ctx context.Context, arg ListPublishedKolPackagesParams) ([]ListPublishedKolPackagesRow, error)
ListQuestions(ctx context.Context, arg ListQuestionsParams) ([]ListQuestionsRow, error)
ListScheduleTasks(ctx context.Context, arg ListScheduleTasksParams) ([]ListScheduleTasksRow, error)
ListSubscriptionPromptsByTenant(ctx context.Context, tenantID int64) ([]ListSubscriptionPromptsByTenantRow, error)
ListTemplates(ctx context.Context, tenantID int64) ([]ListTemplatesRow, error)
MarkImagesInFolderPendingDelete(ctx context.Context, arg MarkImagesInFolderPendingDeleteParams) error
MarkKolAssistCompleted(ctx context.Context, arg MarkKolAssistCompletedParams) error
MarkKolAssistFailed(ctx context.Context, arg MarkKolAssistFailedParams) error
MarkKolAssistStarted(ctx context.Context, arg MarkKolAssistStartedParams) error
MarkKolUsageCompleted(ctx context.Context, arg MarkKolUsageCompletedParams) error
MarkKolUsageCompletedByTask(ctx context.Context, arg MarkKolUsageCompletedByTaskParams) error
MarkKolUsageFailed(ctx context.Context, arg MarkKolUsageFailedParams) error
MarkKolUsageFailedByTask(ctx context.Context, arg MarkKolUsageFailedByTaskParams) error
NextKolPromptRevisionNo(ctx context.Context, arg NextKolPromptRevisionNoParams) (int32, error)
RefundReservation(ctx context.Context, arg RefundReservationParams) error
ReleaseImageStorageQuota(ctx context.Context, arg ReleaseImageStorageQuotaParams) error
RevokeKolSubscription(ctx context.Context, arg RevokeKolSubscriptionParams) error
RevokeSubscriptionPromptsByPrompt(ctx context.Context, arg RevokeSubscriptionPromptsByPromptParams) error
RevokeSubscriptionPromptsBySubscription(ctx context.Context, arg RevokeSubscriptionPromptsBySubscriptionParams) error
SoftDeleteArticle(ctx context.Context, arg SoftDeleteArticleParams) error
SoftDeleteBrand(ctx context.Context, arg SoftDeleteBrandParams) error
SoftDeleteCompetitor(ctx context.Context, arg SoftDeleteCompetitorParams) error
SoftDeleteCompetitorsByBrand(ctx context.Context, arg SoftDeleteCompetitorsByBrandParams) error
SoftDeleteKeyword(ctx context.Context, arg SoftDeleteKeywordParams) error
SoftDeleteKeywordsByBrand(ctx context.Context, arg SoftDeleteKeywordsByBrandParams) error
SoftDeleteKolPackage(ctx context.Context, arg SoftDeleteKolPackageParams) error
SoftDeleteKolPrompt(ctx context.Context, arg SoftDeleteKolPromptParams) error
SoftDeletePromptRule(ctx context.Context, arg SoftDeletePromptRuleParams) error
SoftDeletePromptRuleGroup(ctx context.Context, arg SoftDeletePromptRuleGroupParams) error
SoftDeleteQuestion(ctx context.Context, arg SoftDeleteQuestionParams) error
@@ -104,6 +150,13 @@ type Querier interface {
UpdateImageAssetStatus(ctx context.Context, arg UpdateImageAssetStatusParams) error
UpdateImageFolder(ctx context.Context, arg UpdateImageFolderParams) error
UpdateKeyword(ctx context.Context, arg UpdateKeywordParams) error
UpdateKolPackage(ctx context.Context, arg UpdateKolPackageParams) error
UpdateKolPackageStatus(ctx context.Context, arg UpdateKolPackageStatusParams) error
UpdateKolProfile(ctx context.Context, arg UpdateKolProfileParams) error
UpdateKolPromptDraftRevision(ctx context.Context, arg UpdateKolPromptDraftRevisionParams) error
UpdateKolPromptMetadata(ctx context.Context, arg UpdateKolPromptMetadataParams) error
UpdateKolPromptPublishedRevision(ctx context.Context, arg UpdateKolPromptPublishedRevisionParams) error
UpdateKolPromptStatus(ctx context.Context, arg UpdateKolPromptStatusParams) error
UpdatePromptRule(ctx context.Context, arg UpdatePromptRuleParams) error
UpdatePromptRuleGroup(ctx context.Context, arg UpdatePromptRuleGroupParams) error
UpdatePromptRuleStatus(ctx context.Context, arg UpdatePromptRuleStatusParams) error
@@ -0,0 +1,34 @@
-- name: CreateKolAssistTask :exec
INSERT INTO kol_assist_tasks (id, tenant_id, kol_profile_id, prompt_id,
operator_id, task_type, status, request_json)
VALUES (sqlc.arg(id), sqlc.arg(tenant_id)::bigint, sqlc.arg(kol_profile_id),
sqlc.arg(prompt_id), sqlc.arg(operator_id),
sqlc.arg(task_type), 'queued', sqlc.arg(request_json)::jsonb);
-- name: GetKolAssistTask :one
SELECT id, tenant_id, kol_profile_id, prompt_id, operator_id, task_type,
status, request_json, result_json, error_message,
started_at, completed_at, created_at, updated_at
FROM kol_assist_tasks
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: MarkKolAssistStarted :exec
UPDATE kol_assist_tasks
SET status = 'running', started_at = NOW(), updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: MarkKolAssistCompleted :exec
UPDATE kol_assist_tasks
SET status = 'completed', result_json = sqlc.arg(result_json)::jsonb,
completed_at = NOW(), updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: MarkKolAssistFailed :exec
UPDATE kol_assist_tasks
SET status = 'failed', error_message = sqlc.arg(error_message),
completed_at = NOW(), updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
@@ -0,0 +1,46 @@
-- name: ListPublishedKolPackages :many
-- Cross-tenant read: marketplace intentionally spans tenants.
-- tenant_id appears via kol_profiles.tenant_id join only, so this file is exempt from check_tenant_scope.sh.
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,
(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') AS subscriber_count
FROM kol_packages kp
JOIN kol_profiles pf ON pf.id = kp.kol_profile_id
AND pf.status = 'active'
AND pf.market_enabled = TRUE
AND pf.deleted_at IS NULL
WHERE kp.status = 'published'
AND kp.deleted_at IS NULL
AND (sqlc.narg('industry')::text IS NULL OR kp.industry = sqlc.narg('industry'))
AND (sqlc.narg('keyword')::text IS NULL OR kp.name ILIKE '%' || sqlc.narg('keyword') || '%')
ORDER BY kp.updated_at DESC
LIMIT sqlc.arg('limit') OFFSET sqlc.arg('offset');
-- 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
FROM kol_packages kp
JOIN kol_profiles pf ON pf.id = kp.kol_profile_id
AND pf.status = 'active'
AND pf.market_enabled = TRUE
AND pf.deleted_at IS NULL
WHERE kp.id = sqlc.arg(id)
AND kp.status = 'published'
AND kp.deleted_at IS NULL;
-- name: ListPublicPromptsForPackage :many
SELECT p.id, p.name, p.platform_hint, p.status,
p.published_revision_no, p.created_at
FROM kol_prompts p
WHERE p.package_id = sqlc.arg(package_id)
AND p.status = 'active'
AND p.published_revision_no IS NOT NULL
AND p.deleted_at IS NULL
ORDER BY p.sort_order ASC;
@@ -0,0 +1,58 @@
-- name: CreateKolPackage :one
INSERT INTO kol_packages (tenant_id, kol_profile_id, name, description, cover_url, industry, tags, price_note, status)
VALUES (sqlc.arg(tenant_id)::bigint, sqlc.arg(kol_profile_id), sqlc.arg(name),
sqlc.arg(description), sqlc.arg(cover_url), sqlc.arg(industry),
sqlc.arg(tags)::jsonb, sqlc.arg(price_note), 'draft')
RETURNING id, tenant_id, kol_profile_id, name, description, cover_url,
industry, tags, price_note, status, created_at, updated_at;
-- name: GetKolPackageByID :one
SELECT id, tenant_id, kol_profile_id, name, description, cover_url,
industry, tags, price_note, status, created_at, updated_at
FROM kol_packages
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: ListKolPackagesByProfile :many
SELECT id, tenant_id, kol_profile_id, name, description, cover_url,
industry, tags, price_note, status, created_at, updated_at
FROM kol_packages
WHERE kol_profile_id = sqlc.arg(kol_profile_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL
ORDER BY created_at DESC;
-- name: ListKolPackageIDsByProfile :many
SELECT id
FROM kol_packages
WHERE kol_profile_id = sqlc.arg(kol_profile_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: UpdateKolPackage :exec
UPDATE kol_packages
SET name = sqlc.arg(name),
description = sqlc.arg(description),
cover_url = sqlc.arg(cover_url),
industry = sqlc.arg(industry),
tags = sqlc.arg(tags)::jsonb,
price_note = sqlc.arg(price_note),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: UpdateKolPackageStatus :exec
UPDATE kol_packages
SET status = sqlc.arg(status),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: SoftDeleteKolPackage :exec
UPDATE kol_packages SET deleted_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
@@ -0,0 +1,23 @@
-- name: GetKolProfileByUser :one
SELECT id, tenant_id, user_id, display_name, bio, avatar_url,
market_enabled, status, created_at, updated_at
FROM kol_profiles
WHERE user_id = sqlc.arg(user_id)::bigint
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: GetKolProfileByID :one
SELECT id, tenant_id, user_id, display_name, bio, avatar_url,
market_enabled, status, created_at, updated_at
FROM kol_profiles
WHERE id = sqlc.arg(id) AND deleted_at IS NULL;
-- name: UpdateKolProfile :exec
UPDATE kol_profiles
SET display_name = sqlc.arg(display_name),
bio = sqlc.arg(bio),
avatar_url = sqlc.arg(avatar_url),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
@@ -0,0 +1,105 @@
-- name: CreateKolPrompt :one
INSERT INTO kol_prompts (tenant_id, package_id, name, platform_hint, sort_order, created_by, updated_by)
VALUES (sqlc.arg(tenant_id)::bigint, sqlc.arg(package_id), sqlc.arg(name),
sqlc.arg(platform_hint), sqlc.arg(sort_order),
sqlc.arg(created_by), sqlc.arg(created_by))
RETURNING id, tenant_id, package_id, name, platform_hint, status, sort_order,
published_revision_no, draft_revision_no, created_by, updated_by,
created_at, updated_at;
-- name: GetKolPromptByID :one
SELECT id, tenant_id, package_id, name, platform_hint, status, sort_order,
published_revision_no, draft_revision_no, created_by, updated_by,
created_at, updated_at
FROM kol_prompts
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: ListKolPromptsByPackage :many
SELECT id, tenant_id, package_id, name, platform_hint, status, sort_order,
published_revision_no, draft_revision_no, created_by, updated_by,
created_at, updated_at
FROM kol_prompts
WHERE package_id = sqlc.arg(package_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL
ORDER BY sort_order ASC, created_at ASC;
-- name: ListActiveKolPromptsByPackage :many
SELECT id, tenant_id, package_id, published_revision_no
FROM kol_prompts
WHERE package_id = sqlc.arg(package_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND status = 'active'
AND published_revision_no IS NOT NULL
AND deleted_at IS NULL
ORDER BY sort_order ASC;
-- name: UpdateKolPromptMetadata :exec
UPDATE kol_prompts
SET name = sqlc.arg(name),
platform_hint = sqlc.arg(platform_hint),
sort_order = sqlc.arg(sort_order),
updated_by = sqlc.arg(updated_by),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: UpdateKolPromptPublishedRevision :exec
UPDATE kol_prompts
SET published_revision_no = sqlc.arg(revision_no),
status = 'active',
updated_by = sqlc.arg(updated_by),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: UpdateKolPromptDraftRevision :exec
UPDATE kol_prompts
SET draft_revision_no = sqlc.arg(revision_no),
updated_by = sqlc.arg(updated_by),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: UpdateKolPromptStatus :exec
UPDATE kol_prompts
SET status = sqlc.arg(status),
updated_by = sqlc.arg(updated_by),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: SoftDeleteKolPrompt :exec
UPDATE kol_prompts SET deleted_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint
AND deleted_at IS NULL;
-- name: CreateKolPromptRevision :one
INSERT INTO kol_prompt_revisions (tenant_id, prompt_id, revision_no, prompt_asset_key,
schema_json, card_config_json, created_by)
VALUES (sqlc.arg(tenant_id)::bigint, sqlc.arg(prompt_id), sqlc.arg(revision_no),
sqlc.arg(prompt_asset_key), sqlc.arg(schema_json)::jsonb,
sqlc.arg(card_config_json)::jsonb, sqlc.arg(created_by))
RETURNING id, prompt_id, revision_no, prompt_asset_key, schema_json,
card_config_json, created_by, created_at;
-- name: GetKolPromptRevision :one
SELECT id, prompt_id, revision_no, prompt_asset_key, schema_json,
card_config_json, created_by, created_at
FROM kol_prompt_revisions
WHERE prompt_id = sqlc.arg(prompt_id)
AND revision_no = sqlc.arg(revision_no)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: NextKolPromptRevisionNo :one
SELECT COALESCE(MAX(revision_no), 0) + 1 AS next_revision_no
FROM kol_prompt_revisions
WHERE prompt_id = sqlc.arg(prompt_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
@@ -0,0 +1,90 @@
-- name: CreateKolSubscription :one
INSERT INTO kol_subscriptions (tenant_id, package_id, status)
VALUES (sqlc.arg(tenant_id)::bigint, sqlc.arg(package_id), 'pending')
RETURNING id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at;
-- name: GetKolSubscriptionByID :one
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)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: GetActiveKolSubscription :one
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE tenant_id = sqlc.arg(tenant_id)::bigint
AND package_id = sqlc.arg(package_id)
AND status IN ('pending', 'active');
-- name: ListKolSubscriptions :many
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE tenant_id = sqlc.arg(tenant_id)::bigint
ORDER BY created_at DESC;
-- name: ListActiveSubscribersForPackage :many
SELECT id, tenant_id, package_id, status, approved_by, start_at, end_at, created_at, updated_at
FROM kol_subscriptions
WHERE package_id = sqlc.arg(package_id)
AND tenant_id IS NOT NULL
AND status = 'active';
-- name: ApproveKolSubscription :exec
UPDATE kol_subscriptions
SET status = 'active',
approved_by = sqlc.arg(approved_by),
start_at = NOW(),
end_at = sqlc.arg(end_at),
updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: RevokeKolSubscription :exec
UPDATE kol_subscriptions
SET status = 'revoked', updated_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: CreateSubscriptionPrompt :exec
INSERT INTO kol_subscription_prompts (tenant_id, subscription_id, package_id, prompt_id, status)
VALUES (sqlc.arg(tenant_id)::bigint, sqlc.arg(subscription_id),
sqlc.arg(package_id), sqlc.arg(prompt_id), 'active')
ON CONFLICT (subscription_id, prompt_id) DO NOTHING;
-- name: ListSubscriptionPromptsByTenant :many
SELECT sp.id, sp.tenant_id, sp.subscription_id, sp.package_id, sp.prompt_id,
sp.status, sp.granted_at, sp.revoked_at,
p.name AS prompt_name, p.platform_hint, p.published_revision_no,
k.name AS package_name
FROM kol_subscription_prompts sp
JOIN kol_prompts p ON p.id = sp.prompt_id AND p.deleted_at IS NULL
JOIN kol_packages k ON k.id = sp.package_id AND k.deleted_at IS NULL
WHERE sp.tenant_id = sqlc.arg(tenant_id)::bigint
AND sp.status = 'active'
ORDER BY sp.granted_at DESC;
-- 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,
s.status AS subscription_status, s.end_at AS subscription_end_at,
p.name AS prompt_name, p.platform_hint, p.status AS prompt_status,
p.published_revision_no,
k.name AS package_name, k.status AS package_status
FROM kol_subscription_prompts sp
JOIN kol_subscriptions s ON s.id = sp.subscription_id
JOIN kol_prompts p ON p.id = sp.prompt_id AND p.deleted_at IS NULL
JOIN kol_packages k ON k.id = sp.package_id AND k.deleted_at IS NULL
WHERE sp.id = sqlc.arg(id)
AND sp.tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: RevokeSubscriptionPromptsBySubscription :exec
UPDATE kol_subscription_prompts
SET status = 'revoked', revoked_at = NOW(), updated_at = NOW()
WHERE subscription_id = sqlc.arg(subscription_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: RevokeSubscriptionPromptsByPrompt :exec
UPDATE kol_subscription_prompts
SET status = 'revoked', revoked_at = NOW(), updated_at = NOW()
WHERE prompt_id = sqlc.arg(prompt_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
@@ -0,0 +1,84 @@
-- name: CreateKolUsageLog :one
INSERT INTO kol_usage_logs (tenant_id, subscription_id, subscription_prompt_id,
package_id, prompt_id, prompt_revision_no,
generation_task_id, status, variables_snapshot,
schema_snapshot, rendered_prompt_hash)
VALUES (sqlc.arg(tenant_id)::bigint, sqlc.arg(subscription_id),
sqlc.arg(subscription_prompt_id), sqlc.arg(package_id),
sqlc.arg(prompt_id), sqlc.arg(prompt_revision_no),
sqlc.arg(generation_task_id), 'pending',
sqlc.arg(variables_snapshot)::jsonb, sqlc.arg(schema_snapshot)::jsonb,
sqlc.arg(rendered_prompt_hash))
RETURNING id, tenant_id, generation_task_id, status, created_at;
-- name: MarkKolUsageCompleted :exec
UPDATE kol_usage_logs
SET status = 'completed', article_id = sqlc.arg(article_id),
finished_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: MarkKolUsageFailed :exec
UPDATE kol_usage_logs
SET status = 'failed', error_message = sqlc.arg(error_message),
finished_at = NOW()
WHERE id = sqlc.arg(id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: MarkKolUsageCompletedByTask :exec
UPDATE kol_usage_logs
SET status = 'completed', article_id = sqlc.arg(article_id), finished_at = NOW()
WHERE generation_task_id = sqlc.arg(generation_task_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: MarkKolUsageFailedByTask :exec
UPDATE kol_usage_logs
SET status = 'failed', error_message = sqlc.arg(error_message), finished_at = NOW()
WHERE generation_task_id = sqlc.arg(generation_task_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: GetKolUsageByGenerationTask :one
SELECT id, tenant_id, package_id, prompt_id, status, created_at
FROM kol_usage_logs
WHERE generation_task_id = sqlc.arg(generation_task_id)
AND tenant_id = sqlc.arg(tenant_id)::bigint;
-- name: KolDashboardOverview :one
SELECT
(SELECT COUNT(DISTINCT s.tenant_id) FROM kol_subscriptions s
WHERE s.package_id = ANY(sqlc.arg(package_ids)::bigint[]) AND s.status='active'
AND (s.end_at IS NULL OR s.end_at > NOW())) AS total_subs,
(SELECT COUNT(*) FROM kol_subscriptions s
WHERE s.package_id = ANY(sqlc.arg(package_ids)::bigint[])
AND s.status='active'
AND s.created_at >= date_trunc('month', NOW())) AS month_subs,
(SELECT COUNT(*) FROM kol_usage_logs u
WHERE u.package_id = ANY(sqlc.arg(package_ids)::bigint[])
AND u.tenant_id IS NOT NULL) AS total_usage,
(SELECT COUNT(*) FROM kol_usage_logs u
WHERE u.package_id = ANY(sqlc.arg(package_ids)::bigint[])
AND u.tenant_id IS NOT NULL
AND u.created_at >= date_trunc('month', NOW())) AS month_usage,
(SELECT COUNT(*) FROM kol_usage_logs u
WHERE u.package_id = ANY(sqlc.arg(package_ids)::bigint[])
AND u.tenant_id IS NOT NULL
AND u.status='failed') AS failure_count;
-- name: KolDashboardTrend :many
SELECT date_trunc('day', u.created_at)::date AS d,
COUNT(*) FILTER (WHERE u.status='completed') AS usages
FROM kol_usage_logs u
WHERE u.package_id = ANY(sqlc.arg(package_ids)::bigint[])
AND u.tenant_id IS NOT NULL
AND u.created_at >= NOW() - sqlc.arg(period_days)::int * INTERVAL '1 day'
GROUP BY d
ORDER BY d ASC;
-- name: KolUsageCountByPackage :many
SELECT package_id, COUNT(*) AS total,
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed,
SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed
FROM kol_usage_logs
WHERE package_id = ANY(sqlc.arg(package_ids)::bigint[])
AND tenant_id IS NOT NULL
GROUP BY package_id;