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.
560 lines
16 KiB
Go
560 lines
16 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
// source: brand.sql
|
|
|
|
package generated
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const createBrand = `-- name: CreateBrand :one
|
|
INSERT INTO brands (tenant_id, name, description, status)
|
|
VALUES ($1, $2, $3, 'active')
|
|
RETURNING id, created_at
|
|
`
|
|
|
|
type CreateBrandParams struct {
|
|
TenantID int64 `json:"tenant_id"`
|
|
Name string `json:"name"`
|
|
Description pgtype.Text `json:"description"`
|
|
}
|
|
|
|
type CreateBrandRow struct {
|
|
ID int64 `json:"id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
func (q *Queries) CreateBrand(ctx context.Context, arg CreateBrandParams) (CreateBrandRow, error) {
|
|
row := q.db.QueryRow(ctx, createBrand, arg.TenantID, arg.Name, arg.Description)
|
|
var i CreateBrandRow
|
|
err := row.Scan(&i.ID, &i.CreatedAt)
|
|
return i, err
|
|
}
|
|
|
|
const createCompetitor = `-- name: CreateCompetitor :one
|
|
INSERT INTO competitors (tenant_id, brand_id, name, website, description, product_lines_json)
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
RETURNING id, created_at
|
|
`
|
|
|
|
type CreateCompetitorParams struct {
|
|
TenantID int64 `json:"tenant_id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
Name string `json:"name"`
|
|
Website pgtype.Text `json:"website"`
|
|
Description pgtype.Text `json:"description"`
|
|
ProductLinesJson []byte `json:"product_lines_json"`
|
|
}
|
|
|
|
type CreateCompetitorRow struct {
|
|
ID int64 `json:"id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
func (q *Queries) CreateCompetitor(ctx context.Context, arg CreateCompetitorParams) (CreateCompetitorRow, error) {
|
|
row := q.db.QueryRow(ctx, createCompetitor,
|
|
arg.TenantID,
|
|
arg.BrandID,
|
|
arg.Name,
|
|
arg.Website,
|
|
arg.Description,
|
|
arg.ProductLinesJson,
|
|
)
|
|
var i CreateCompetitorRow
|
|
err := row.Scan(&i.ID, &i.CreatedAt)
|
|
return i, err
|
|
}
|
|
|
|
const createKeyword = `-- name: CreateKeyword :one
|
|
INSERT INTO brand_keywords (tenant_id, brand_id, name, status)
|
|
VALUES ($1, $2, $3, 'active')
|
|
RETURNING id, created_at
|
|
`
|
|
|
|
type CreateKeywordParams struct {
|
|
TenantID int64 `json:"tenant_id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type CreateKeywordRow struct {
|
|
ID int64 `json:"id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
func (q *Queries) CreateKeyword(ctx context.Context, arg CreateKeywordParams) (CreateKeywordRow, error) {
|
|
row := q.db.QueryRow(ctx, createKeyword, arg.TenantID, arg.BrandID, arg.Name)
|
|
var i CreateKeywordRow
|
|
err := row.Scan(&i.ID, &i.CreatedAt)
|
|
return i, err
|
|
}
|
|
|
|
const createQuestion = `-- name: CreateQuestion :one
|
|
INSERT INTO brand_questions (tenant_id, brand_id, keyword_id, question_text, status)
|
|
VALUES ($1, $2, $3, $4, 'active')
|
|
RETURNING id
|
|
`
|
|
|
|
type CreateQuestionParams struct {
|
|
TenantID int64 `json:"tenant_id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
KeywordID int64 `json:"keyword_id"`
|
|
QuestionText string `json:"question_text"`
|
|
}
|
|
|
|
func (q *Queries) CreateQuestion(ctx context.Context, arg CreateQuestionParams) (int64, error) {
|
|
row := q.db.QueryRow(ctx, createQuestion,
|
|
arg.TenantID,
|
|
arg.BrandID,
|
|
arg.KeywordID,
|
|
arg.QuestionText,
|
|
)
|
|
var id int64
|
|
err := row.Scan(&id)
|
|
return id, err
|
|
}
|
|
|
|
const getBrandByID = `-- name: GetBrandByID :one
|
|
SELECT id, tenant_id, name, description, status, created_at, updated_at
|
|
FROM brands
|
|
WHERE id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
`
|
|
|
|
type GetBrandByIDParams struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
type GetBrandByIDRow struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
Name string `json:"name"`
|
|
Description pgtype.Text `json:"description"`
|
|
Status string `json:"status"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
func (q *Queries) GetBrandByID(ctx context.Context, arg GetBrandByIDParams) (GetBrandByIDRow, error) {
|
|
row := q.db.QueryRow(ctx, getBrandByID, arg.ID, arg.TenantID)
|
|
var i GetBrandByIDRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.TenantID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&i.Status,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const listBrands = `-- name: ListBrands :many
|
|
SELECT id, tenant_id, name, description, status, created_at, updated_at
|
|
FROM brands
|
|
WHERE tenant_id = $1 AND deleted_at IS NULL
|
|
ORDER BY created_at DESC
|
|
`
|
|
|
|
type ListBrandsRow struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
Name string `json:"name"`
|
|
Description pgtype.Text `json:"description"`
|
|
Status string `json:"status"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
func (q *Queries) ListBrands(ctx context.Context, tenantID int64) ([]ListBrandsRow, error) {
|
|
rows, err := q.db.Query(ctx, listBrands, tenantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListBrandsRow
|
|
for rows.Next() {
|
|
var i ListBrandsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TenantID,
|
|
&i.Name,
|
|
&i.Description,
|
|
&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 listCompetitors = `-- name: ListCompetitors :many
|
|
SELECT id, tenant_id, brand_id, name, website, description, product_lines_json, created_at, updated_at
|
|
FROM competitors
|
|
WHERE brand_id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
ORDER BY created_at DESC
|
|
`
|
|
|
|
type ListCompetitorsParams struct {
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
type ListCompetitorsRow struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
Name string `json:"name"`
|
|
Website pgtype.Text `json:"website"`
|
|
Description pgtype.Text `json:"description"`
|
|
ProductLinesJson []byte `json:"product_lines_json"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
func (q *Queries) ListCompetitors(ctx context.Context, arg ListCompetitorsParams) ([]ListCompetitorsRow, error) {
|
|
rows, err := q.db.Query(ctx, listCompetitors, arg.BrandID, arg.TenantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListCompetitorsRow
|
|
for rows.Next() {
|
|
var i ListCompetitorsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TenantID,
|
|
&i.BrandID,
|
|
&i.Name,
|
|
&i.Website,
|
|
&i.Description,
|
|
&i.ProductLinesJson,
|
|
&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 listKeywords = `-- name: ListKeywords :many
|
|
SELECT id, tenant_id, brand_id, name, status, created_at, updated_at
|
|
FROM brand_keywords
|
|
WHERE brand_id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
ORDER BY created_at DESC
|
|
`
|
|
|
|
type ListKeywordsParams struct {
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
type ListKeywordsRow struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
Name string `json:"name"`
|
|
Status string `json:"status"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
UpdatedAt pgtype.Timestamptz `json:"updated_at"`
|
|
}
|
|
|
|
func (q *Queries) ListKeywords(ctx context.Context, arg ListKeywordsParams) ([]ListKeywordsRow, error) {
|
|
rows, err := q.db.Query(ctx, listKeywords, arg.BrandID, arg.TenantID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListKeywordsRow
|
|
for rows.Next() {
|
|
var i ListKeywordsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TenantID,
|
|
&i.BrandID,
|
|
&i.Name,
|
|
&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 listQuestions = `-- name: ListQuestions :many
|
|
SELECT q.id, q.tenant_id, q.brand_id, q.keyword_id, q.question_text, q.status, q.created_at
|
|
FROM brand_questions q
|
|
WHERE q.brand_id = $1 AND q.tenant_id = $2 AND q.deleted_at IS NULL
|
|
AND ($3::bigint IS NULL OR q.keyword_id = $3)
|
|
ORDER BY q.created_at DESC
|
|
`
|
|
|
|
type ListQuestionsParams struct {
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
KeywordID pgtype.Int8 `json:"keyword_id"`
|
|
}
|
|
|
|
type ListQuestionsRow struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
KeywordID int64 `json:"keyword_id"`
|
|
QuestionText string `json:"question_text"`
|
|
Status string `json:"status"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
func (q *Queries) ListQuestions(ctx context.Context, arg ListQuestionsParams) ([]ListQuestionsRow, error) {
|
|
rows, err := q.db.Query(ctx, listQuestions, arg.BrandID, arg.TenantID, arg.KeywordID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListQuestionsRow
|
|
for rows.Next() {
|
|
var i ListQuestionsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.TenantID,
|
|
&i.BrandID,
|
|
&i.KeywordID,
|
|
&i.QuestionText,
|
|
&i.Status,
|
|
&i.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const softDeleteBrand = `-- name: SoftDeleteBrand :exec
|
|
UPDATE brands SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteBrandParams struct {
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteBrand(ctx context.Context, arg SoftDeleteBrandParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteBrand, arg.ID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const softDeleteCompetitor = `-- name: SoftDeleteCompetitor :exec
|
|
UPDATE competitors SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE id = $1 AND brand_id = $2 AND tenant_id = $3 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteCompetitorParams struct {
|
|
ID int64 `json:"id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteCompetitor(ctx context.Context, arg SoftDeleteCompetitorParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteCompetitor, arg.ID, arg.BrandID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const softDeleteCompetitorsByBrand = `-- name: SoftDeleteCompetitorsByBrand :exec
|
|
UPDATE competitors SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE brand_id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteCompetitorsByBrandParams struct {
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteCompetitorsByBrand(ctx context.Context, arg SoftDeleteCompetitorsByBrandParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteCompetitorsByBrand, arg.BrandID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const softDeleteKeyword = `-- name: SoftDeleteKeyword :exec
|
|
UPDATE brand_keywords SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE id = $1 AND brand_id = $2 AND tenant_id = $3 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteKeywordParams struct {
|
|
ID int64 `json:"id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteKeyword(ctx context.Context, arg SoftDeleteKeywordParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteKeyword, arg.ID, arg.BrandID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const softDeleteKeywordsByBrand = `-- name: SoftDeleteKeywordsByBrand :exec
|
|
UPDATE brand_keywords SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE brand_id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteKeywordsByBrandParams struct {
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteKeywordsByBrand(ctx context.Context, arg SoftDeleteKeywordsByBrandParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteKeywordsByBrand, arg.BrandID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const softDeleteQuestion = `-- name: SoftDeleteQuestion :exec
|
|
UPDATE brand_questions SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE id = $1 AND brand_id = $2 AND tenant_id = $3 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteQuestionParams struct {
|
|
ID int64 `json:"id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteQuestion(ctx context.Context, arg SoftDeleteQuestionParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteQuestion, arg.ID, arg.BrandID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const softDeleteQuestionsByBrand = `-- name: SoftDeleteQuestionsByBrand :exec
|
|
UPDATE brand_questions SET deleted_at = NOW(), updated_at = NOW()
|
|
WHERE brand_id = $1 AND tenant_id = $2 AND deleted_at IS NULL
|
|
`
|
|
|
|
type SoftDeleteQuestionsByBrandParams struct {
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) SoftDeleteQuestionsByBrand(ctx context.Context, arg SoftDeleteQuestionsByBrandParams) error {
|
|
_, err := q.db.Exec(ctx, softDeleteQuestionsByBrand, arg.BrandID, arg.TenantID)
|
|
return err
|
|
}
|
|
|
|
const updateBrand = `-- name: UpdateBrand :exec
|
|
UPDATE brands SET name = $1, description = $2, updated_at = NOW()
|
|
WHERE id = $3 AND tenant_id = $4 AND deleted_at IS NULL
|
|
`
|
|
|
|
type UpdateBrandParams struct {
|
|
Name string `json:"name"`
|
|
Description pgtype.Text `json:"description"`
|
|
ID int64 `json:"id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateBrand(ctx context.Context, arg UpdateBrandParams) error {
|
|
_, err := q.db.Exec(ctx, updateBrand,
|
|
arg.Name,
|
|
arg.Description,
|
|
arg.ID,
|
|
arg.TenantID,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const updateCompetitor = `-- name: UpdateCompetitor :exec
|
|
UPDATE competitors SET name = $1, website = $2,
|
|
description = $3, product_lines_json = $4, updated_at = NOW()
|
|
WHERE id = $5 AND brand_id = $6 AND tenant_id = $7 AND deleted_at IS NULL
|
|
`
|
|
|
|
type UpdateCompetitorParams struct {
|
|
Name string `json:"name"`
|
|
Website pgtype.Text `json:"website"`
|
|
Description pgtype.Text `json:"description"`
|
|
ProductLinesJson []byte `json:"product_lines_json"`
|
|
ID int64 `json:"id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateCompetitor(ctx context.Context, arg UpdateCompetitorParams) error {
|
|
_, err := q.db.Exec(ctx, updateCompetitor,
|
|
arg.Name,
|
|
arg.Website,
|
|
arg.Description,
|
|
arg.ProductLinesJson,
|
|
arg.ID,
|
|
arg.BrandID,
|
|
arg.TenantID,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const updateKeyword = `-- name: UpdateKeyword :exec
|
|
UPDATE brand_keywords SET name = $1, updated_at = NOW()
|
|
WHERE id = $2 AND brand_id = $3 AND tenant_id = $4 AND deleted_at IS NULL
|
|
`
|
|
|
|
type UpdateKeywordParams struct {
|
|
Name string `json:"name"`
|
|
ID int64 `json:"id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateKeyword(ctx context.Context, arg UpdateKeywordParams) error {
|
|
_, err := q.db.Exec(ctx, updateKeyword,
|
|
arg.Name,
|
|
arg.ID,
|
|
arg.BrandID,
|
|
arg.TenantID,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const updateQuestion = `-- name: UpdateQuestion :exec
|
|
UPDATE brand_questions SET question_text = $1, updated_at = NOW()
|
|
WHERE id = $2 AND brand_id = $3 AND tenant_id = $4 AND deleted_at IS NULL
|
|
`
|
|
|
|
type UpdateQuestionParams struct {
|
|
QuestionText string `json:"question_text"`
|
|
ID int64 `json:"id"`
|
|
BrandID int64 `json:"brand_id"`
|
|
TenantID int64 `json:"tenant_id"`
|
|
}
|
|
|
|
func (q *Queries) UpdateQuestion(ctx context.Context, arg UpdateQuestionParams) error {
|
|
_, err := q.db.Exec(ctx, updateQuestion,
|
|
arg.QuestionText,
|
|
arg.ID,
|
|
arg.BrandID,
|
|
arg.TenantID,
|
|
)
|
|
return err
|
|
}
|