36451a613d
- Added comprehensive technical design document for AI Brand Monitoring System V5, outlining system architecture, data models, sampling strategies, and monitoring protocols. - Key changes include a shift to a sampling-based trend monitoring approach, updated data collection and storage strategies, and new metrics for performance evaluation. - Implemented migration scripts to support the flattening of brand questions and versioning of question texts, ensuring historical data integrity and version control.
163 lines
4.8 KiB
Go
163 lines
4.8 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
// source: workspace.sql
|
|
|
|
package generated
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const countArticlesByTenant = `-- name: CountArticlesByTenant :one
|
|
SELECT COUNT(*) FROM articles
|
|
WHERE tenant_id = $1 AND deleted_at IS NULL
|
|
`
|
|
|
|
func (q *Queries) CountArticlesByTenant(ctx context.Context, tenantID int64) (int64, error) {
|
|
row := q.db.QueryRow(ctx, countArticlesByTenant, tenantID)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const countBrandsByTenant = `-- name: CountBrandsByTenant :one
|
|
SELECT COUNT(*) FROM brands
|
|
WHERE tenant_id = $1 AND deleted_at IS NULL
|
|
`
|
|
|
|
func (q *Queries) CountBrandsByTenant(ctx context.Context, tenantID int64) (int64, error) {
|
|
row := q.db.QueryRow(ctx, countBrandsByTenant, tenantID)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const countPublishedArticlesByTenant = `-- name: CountPublishedArticlesByTenant :one
|
|
SELECT COUNT(*) FROM articles
|
|
WHERE tenant_id = $1 AND publish_status = 'success' AND deleted_at IS NULL
|
|
`
|
|
|
|
func (q *Queries) CountPublishedArticlesByTenant(ctx context.Context, tenantID int64) (int64, error) {
|
|
row := q.db.QueryRow(ctx, countPublishedArticlesByTenant, tenantID)
|
|
var count int64
|
|
err := row.Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
const getActivePlanForTenant = `-- name: GetActivePlanForTenant :one
|
|
SELECT p.plan_code, p.name AS plan_name, p.quota_policy_json,
|
|
s.start_at, s.end_at
|
|
FROM tenant_plan_subscriptions s
|
|
JOIN plans p ON p.id = s.plan_id
|
|
WHERE s.tenant_id = $1 AND s.status = 'active' AND s.deleted_at IS NULL
|
|
LIMIT 1
|
|
`
|
|
|
|
type GetActivePlanForTenantRow struct {
|
|
PlanCode string `json:"plan_code"`
|
|
PlanName string `json:"plan_name"`
|
|
QuotaPolicyJson []byte `json:"quota_policy_json"`
|
|
StartAt pgtype.Timestamptz `json:"start_at"`
|
|
EndAt pgtype.Timestamptz `json:"end_at"`
|
|
}
|
|
|
|
func (q *Queries) GetActivePlanForTenant(ctx context.Context, tenantID int64) (GetActivePlanForTenantRow, error) {
|
|
row := q.db.QueryRow(ctx, getActivePlanForTenant, tenantID)
|
|
var i GetActivePlanForTenantRow
|
|
err := row.Scan(
|
|
&i.PlanCode,
|
|
&i.PlanName,
|
|
&i.QuotaPolicyJson,
|
|
&i.StartAt,
|
|
&i.EndAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const getQuotaSummary = `-- name: GetQuotaSummary :one
|
|
SELECT COALESCE(
|
|
(SELECT balance_after FROM tenant_quota_ledgers
|
|
WHERE tenant_id = $1 AND quota_type = 'article_generation'
|
|
ORDER BY created_at DESC LIMIT 1), 0
|
|
)::INT AS balance
|
|
`
|
|
|
|
func (q *Queries) GetQuotaSummary(ctx context.Context, tenantID int64) (int32, error) {
|
|
row := q.db.QueryRow(ctx, getQuotaSummary, tenantID)
|
|
var balance int32
|
|
err := row.Scan(&balance)
|
|
return balance, err
|
|
}
|
|
|
|
const getRecentArticles = `-- name: GetRecentArticles :many
|
|
SELECT a.id, a.generate_status, a.publish_status, a.source_type, a.created_at,
|
|
av.title, av.markdown_content, av.word_count, av.source_label,
|
|
t.template_name,
|
|
COALESCE(
|
|
NULLIF(gt.input_params_json ->> 'generation_mode', ''),
|
|
CASE WHEN a.source_type = 'custom_generation' THEN 'instant'::TEXT ELSE NULL::TEXT END
|
|
) AS generation_mode
|
|
FROM articles a
|
|
LEFT JOIN article_versions av ON av.id = a.current_version_id
|
|
LEFT JOIN article_templates t ON t.id = a.template_id
|
|
LEFT JOIN LATERAL (
|
|
SELECT input_params_json
|
|
FROM generation_tasks
|
|
WHERE article_id = a.id
|
|
ORDER BY created_at DESC
|
|
LIMIT 1
|
|
) gt ON true
|
|
WHERE a.tenant_id = $1 AND a.deleted_at IS NULL
|
|
ORDER BY a.created_at DESC
|
|
LIMIT 10
|
|
`
|
|
|
|
type GetRecentArticlesRow struct {
|
|
ID int64 `json:"id"`
|
|
GenerateStatus string `json:"generate_status"`
|
|
PublishStatus string `json:"publish_status"`
|
|
SourceType string `json:"source_type"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
Title pgtype.Text `json:"title"`
|
|
MarkdownContent pgtype.Text `json:"markdown_content"`
|
|
WordCount pgtype.Int4 `json:"word_count"`
|
|
SourceLabel pgtype.Text `json:"source_label"`
|
|
TemplateName pgtype.Text `json:"template_name"`
|
|
GenerationMode interface{} `json:"generation_mode"`
|
|
}
|
|
|
|
func (q *Queries) GetRecentArticles(ctx context.Context, tenantID int64) ([]GetRecentArticlesRow, error) {
|
|
rows, err := q.db.Query(ctx, getRecentArticles, tenantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []GetRecentArticlesRow
|
|
for rows.Next() {
|
|
var i GetRecentArticlesRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.GenerateStatus,
|
|
&i.PublishStatus,
|
|
&i.SourceType,
|
|
&i.CreatedAt,
|
|
&i.Title,
|
|
&i.MarkdownContent,
|
|
&i.WordCount,
|
|
&i.SourceLabel,
|
|
&i.TemplateName,
|
|
&i.GenerationMode,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|