Merge branch 'imp'

Conflicts:
	dal/dal.go
	dal/db_query/queries.sql
	dal/schema/000017_init.down.sql
	dal/schema/000017_init.up.sql
	dal/schema/000018_init.down.sql
	dal/schema/000018_init.up.sql
	dal/sqlcgen/models.go
	dal/sqlcgen/queries.sql.go
	go.mod
	model/model.go
	repository/account/account.go
	repository/question/question.go
	repository/quiz/quiz.go
	repository/result/result.go
	sqlc.yaml
This commit is contained in:
skeris 2025-05-14 01:38:55 +03:00
commit 8b01e8e76f
14 changed files with 647 additions and 191 deletions

@ -32,10 +32,11 @@ INSERT INTO question (
page,
content,
parent_ids,
updated_at
updated_at,
session
)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)
RETURNING id, created_at, updated_at;
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)
RETURNING id, created_at, updated_at;
-- name: DeleteQuestion :one
UPDATE question SET deleted=true WHERE id=$1 RETURNING question.*;
@ -166,7 +167,7 @@ SELECT * FROM quiz
WHERE
deleted = false AND
archived = false AND
status = 'start' AND
(status = 'start' OR status = 'ai') AND
qid = $1;
-- name: GetQuestionTitle :one
@ -510,24 +511,25 @@ FROM
AND tb.time_interval_end = at.time_interval_end;
-- name: QuestionsStatistics :many
WITH Funnel AS (
WITH QuizAnswers AS (
SELECT
session, start, result, question_id, created_at, content, quiz_id
FROM answer
WHERE answer.quiz_id = $1 AND created_at between TO_TIMESTAMP($2)::timestamp and TO_TIMESTAMP($3)::timestamp
), QuizQuestions AS (SELECT title, page, id from question where quiz_id = $1), Funnel AS (
SELECT
COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false,
COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true,
COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question,
COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result
FROM
answer a
QuizAnswers a
LEFT JOIN (
SELECT DISTINCT a.session, q.id AS qid_true_result
FROM answer a
FROM QuizAnswers a
JOIN question q ON a.question_id = q.id
WHERE a.result = TRUE AND a.quiz_id = $1
) AS q ON a.session = q.session
WHERE
a.quiz_id = $1
AND a.created_at >= TO_TIMESTAMP($2)
AND a.created_at <= TO_TIMESTAMP($3)
),
Results AS (
SELECT
@ -550,16 +552,18 @@ WITH Funnel AS (
LastContent AS (
SELECT
a.question_id,
a.content AS last_answer_content
a.content AS last_answer_content,
a.result,
a.start
FROM
answer a
JOIN (
QuizAnswers a
LEFT JOIN (
SELECT
session,
question_id,
MAX(created_at) AS last_created_at
FROM
answer
QuizAnswers
WHERE
quiz_id = $1
AND start != true
@ -734,48 +738,78 @@ SELECT * FROM usersamo WHERE amoid = $1 AND deleted = false;
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT u.*, COUNT(*) OVER() as total_count
SELECT u.*
FROM usersAmo u
JOIN user_data a ON u.AmoID = a.AmoID
WHERE u.Deleted = false
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetUsersCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM usersAmo u JOIN user_data a ON u.AmoID = a.AmoID WHERE u.Deleted = false;
-- name: GetTagsWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT t.*, COUNT(*) OVER() as total_count
SELECT t.*
FROM tags t JOIN user_data u ON t.AccountID = u.AmoID
WHERE t.Deleted = false
ORDER BY t.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetTagsCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM tags t JOIN user_data u ON t.AccountID = u.AmoID WHERE t.Deleted = false;
-- name: GetStepsWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT s.*, COUNT(*) OVER() as total_count
SELECT s.*
FROM steps s JOIN user_data u ON s.AccountID = u.AmoID
WHERE s.Deleted = false AND PipelineID = $4
WHERE s.Deleted = false AND s.PipelineID = $4
ORDER BY s.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetStepsCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM steps s JOIN user_data u ON s.AccountID = u.AmoID WHERE s.Deleted = false AND s.PipelineID = $2;
-- name: GetPipelinesWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT p.*, COUNT(*) OVER() as total_count
SELECT p.*
FROM pipelines p JOIN user_data u ON p.AccountID = u.AmoID
WHERE p.Deleted = false
ORDER BY p.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetPipelinesCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM pipelines p JOIN user_data u ON p.AccountID = u.AmoID WHERE p.Deleted = false;
-- name: GetFieldsWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT f.*, COUNT(*) OVER() as total_count
SELECT f.*
FROM fields f JOIN user_data u ON f.AccountID = u.AmoID
WHERE f.Deleted = false
ORDER BY f.ID OFFSET ($2 - 1) * $3 LIMIT $3;
-- name: GetFieldsCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM fields f JOIN user_data u ON f.AccountID = u.AmoID WHERE f.Deleted = false;
-- name: UpdateTags :exec
UPDATE tags AS t
SET name = (update_data ->> 'Name')::varchar(512),
@ -831,7 +865,7 @@ WITH user_data AS (
CURRENT_TIMESTAMP
FROM new_tags nt
JOIN user_data ud ON true
ON CONFLICT (amoID, accountID, Entity) DO NOTHING
ON CONFLICT (amoID, accountID, Entity) DO UPDATE SET Deleted = false
RETURNING *
)
SELECT nt.*,ud.AmoID
@ -884,17 +918,17 @@ WITH user_data AS (
FROM json_array_elements($2::json) AS field
), inserted_fields AS(
INSERT INTO fields (amoID, code, accountID, name, Entity, type, createdAt)
SELECT nf.amoID,
nf.code,
ud.AmoID,
nf.name,
nf.Entity,
nf.type,
nf.createdAt
FROM new_fields nf
JOIN user_data ud ON true
ON CONFLICT (amoID, accountID, entity) DO NOTHING
RETURNING *
SELECT nf.amoID,
nf.code,
ud.AmoID,
nf.name,
nf.Entity,
nf.type,
nf.createdAt
FROM new_fields nf
JOIN user_data ud ON true
ON CONFLICT (amoID, accountID, entity) DO UPDATE SET Deleted=false
RETURNING *
)
SELECT nf.*,ud.AmoID
FROM new_fields nf
@ -939,7 +973,7 @@ WHERE NOT EXISTS (
SELECT * FROM tokens WHERE accountID = $1;
-- name: GetQuizRule :one
SELECT * FROM rules WHERE QuizID = $1 AND Deleted = false;
SELECT * FROM rules WHERE QuizID = $1 AND AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $2 AND accountsAmo.Deleted = false) AND Deleted = false;
-- name: SetQuizSettings :one
INSERT INTO rules (AccountID, QuizID, PerformerID, PipelineID, StepID, FieldsRule,TagsToAdd)
@ -949,8 +983,8 @@ RETURNING id;
-- name: ChangeQuizSettings :one
UPDATE rules
SET PerformerID = $1,PipelineID = $2,StepID = $3,FieldsRule = $4, TagsToAdd=$5
WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $6 AND accountsAmo.Deleted = false) AND QuizID = $7 AND Deleted = false
SET PerformerID = $1,PipelineID = $2,StepID = $3,FieldsRule = $4, TagsToAdd=$5, Deleted = false
WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $6 AND accountsAmo.Deleted = false) AND QuizID = $7
RETURNING id;
-- name: GetQuestionListByIDs :many
@ -970,11 +1004,11 @@ VALUES ($1, $2, $3, $4, $5, $6);
-- name: GettingAmoUsersTrueResults :many
SELECT a.quiz_id,a.id,a.result,a.question_id,a.content,a.session,
COALESCE((SELECT a2.utm
FROM answer a2
WHERE a2.start = true AND a2.session = a.session
LIMIT 1), '{}'::jsonb) AS utm
,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM usersAmo u WHERE u.AmoUserID = r.performerid AND u.deleted = false) AS performer_name,u.subdomain,u.accountid,u.driveurl
COALESCE((SELECT a2.utm
FROM answer a2
WHERE a2.start = true AND a2.session = a.session
LIMIT 1), '{}'::jsonb) AS utm
,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM usersAmo u WHERE u.AmoUserID = r.performerid AND u.amoid = r.accountid AND u.deleted = false) AS performer_name,u.subdomain,u.accountid,u.driveurl
FROM answer a
INNER JOIN quiz q ON a.quiz_id = q.id
LEFT JOIN amoCRMStatuses s ON a.id = s.AnswerID
@ -1057,6 +1091,26 @@ INSERT INTO amoContact (AccountID, AmoID, Field) VALUES ($1, $2, $3) RETURNING A
-- name: UpdateAmoContact :exec
UPDATE amoContact SET Field = $1,AmoID=$3 WHERE ID = $2;
-- name: GetQuestionsAI :many
SELECT q.id, q.quiz_id, q.title, q.description, q.questiontype, q.required, q.deleted, q.page, q.content, q.version, q.parent_ids, q.created_at, q.updated_at, q.session FROM question q
WHERE q.quiz_id = $1 AND (q.session = $2 OR q.session = '') AND q.deleted = FALSE
ORDER BY (q.session != '') ASC, --без сессии первые потом с сессией
q.page, --по возрастанию страницы
q.created_at --по времени создания
LIMIT $3 OFFSET $4;
-- name: GetQuestionsAICount :one
SELECT COUNT(*) AS count FROM question WHERE quiz_id = $1 AND (session = $2 OR session = '') AND deleted = FALSE;
-- name: CreateQuizAudience :one
INSERT INTO gigachatAudience (QuizID, Sex, Age) VALUES ($1, $2, $3) RETURNING ID;
-- name: GetQuizAudience :many
SELECT * FROM gigachatAudience WHERE QuizID = $1 AND Deleted = FALSE;
-- name: DeleteQuizAudience :exec
UPDATE gigachatAudience set Deleted = TRUE WHERE QuizID = $1;
-- name: CreateLeadTarget :one
INSERT INTO leadtarget (accountID,type,quizID,target,InviteLink) VALUES ($1,$2,$3,$4,$5) RETURNING *;

@ -1,3 +1,4 @@
ALTER table question DROP column session;
ALTER TABLE account ADD column email varchar(50) NOT NULL default '';
DO $$
@ -7,4 +8,4 @@ DO $$
END IF;
END $$;
DROP TABLE IF EXISTS leadtarget;
DROP TABLE IF EXISTS leadtarget;

@ -1,3 +1,15 @@
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_enum
WHERE enumlabel = 'ai' AND enumtypid = 'quiz_status'::regtype
) THEN
ALTER TYPE quiz_status ADD VALUE 'ai';
END IF;
END $$;
ALTER TABLE question ADD column session varchar(20) NOT NULL DEFAULT '';
AlTER TABLE account DROP column email;
DO $$

@ -1,3 +1,5 @@
DROP TABLE IF EXISTS gigachatAudience;
DROP TABLE IF EXISTS tgAccounts;
DO $$
@ -7,4 +9,4 @@ DO $$
END IF;
END $$;
DROP INDEX IF EXISTS idx_apiid_apihash;
DROP INDEX IF EXISTS idx_apiid_apihash;

@ -1,3 +1,13 @@
CREATE TABLE IF NOT EXISTS gigachatAudience (
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
QuizID BIGINT NOT NULL,
Sex BOOLEAN NOT NULL,
Age VARCHAR(5) NOT NULL,
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_quiz FOREIGN KEY (QuizID) REFERENCES quiz(ID)
);
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'tgAccountStatus') THEN

@ -159,6 +159,14 @@ type Field struct {
Createdat sql.NullTime `db:"createdat" json:"createdat"`
}
type Gigachataudience struct {
ID int64 `db:"id" json:"id"`
Quizid int64 `db:"quizid" json:"quizid"`
Sex bool `db:"sex" json:"sex"`
Age string `db:"age" json:"age"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat sql.NullTime `db:"createdat" json:"createdat"`
}
type Leadtarget struct {
ID int64 `db:"id" json:"id"`
Accountid string `db:"accountid" json:"accountid"`
@ -213,6 +221,7 @@ type Question struct {
ParentIds []int32 `db:"parent_ids" json:"parent_ids"`
CreatedAt sql.NullTime `db:"created_at" json:"created_at"`
UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"`
Session string `db:"session" json:"session"`
}
type Quiz struct {

@ -207,8 +207,8 @@ func (q *Queries) ChangeBitrixQuizSettings(ctx context.Context, arg ChangeBitrix
const changeQuizSettings = `-- name: ChangeQuizSettings :one
UPDATE rules
SET PerformerID = $1,PipelineID = $2,StepID = $3,FieldsRule = $4, TagsToAdd=$5
WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $6 AND accountsAmo.Deleted = false) AND QuizID = $7 AND Deleted = false
SET PerformerID = $1,PipelineID = $2,StepID = $3,FieldsRule = $4, TagsToAdd=$5, Deleted = false
WHERE AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $6 AND accountsAmo.Deleted = false) AND QuizID = $7
RETURNING id
`
@ -537,17 +537,17 @@ WITH user_data AS (
FROM json_array_elements($2::json) AS field
), inserted_fields AS(
INSERT INTO fields (amoID, code, accountID, name, Entity, type, createdAt)
SELECT nf.amoID,
nf.code,
ud.AmoID,
nf.name,
nf.Entity,
nf.type,
nf.createdAt
FROM new_fields nf
JOIN user_data ud ON true
ON CONFLICT (amoID, accountID, entity) DO NOTHING
RETURNING id, amoid, code, accountid, name, entity, type, deleted, createdat
SELECT nf.amoID,
nf.code,
ud.AmoID,
nf.name,
nf.Entity,
nf.type,
nf.createdAt
FROM new_fields nf
JOIN user_data ud ON true
ON CONFLICT (amoID, accountID, entity) DO UPDATE SET Deleted=false
RETURNING id, amoid, code, accountid, name, entity, type, deleted, createdat
)
SELECT nf.amoid, nf.code, nf.name, nf.entity, nf.type, nf.createdat,ud.AmoID
FROM new_fields nf
@ -854,7 +854,7 @@ WITH user_data AS (
CURRENT_TIMESTAMP
FROM new_tags nt
JOIN user_data ud ON true
ON CONFLICT (amoID, accountID, Entity) DO NOTHING
ON CONFLICT (amoID, accountID, Entity) DO UPDATE SET Deleted = false
RETURNING id, amoid, accountid, entity, name, color, deleted, createdat
)
SELECT nt.amoid, nt.entity, nt.name, nt.color,ud.AmoID
@ -1078,6 +1078,7 @@ func (q *Queries) CreateAmoAccount(ctx context.Context, arg CreateAmoAccountPara
return err
}
const createBitrixAccount = `-- name: CreateBitrixAccount :exec
INSERT INTO BitrixAccounts (AccountID, BitrixID, Subdomain)
VALUES ($1, $2, $3)
@ -1099,6 +1100,10 @@ INSERT INTO BitrixTokens (AccountID, RefreshToken, AccessToken, AuthCode, Expira
VALUES ($1, $2, $3, $4, $5, $6)
`
const createQuizAudience = `-- name: CreateQuizAudience :one
INSERT INTO gigachatAudience (QuizID, Sex, Age) VALUES ($1, $2, $3) RETURNING ID
`
type CreateBitrixWebHookParams struct {
Accountid string `db:"accountid" json:"accountid"`
Refreshtoken string `db:"refreshtoken" json:"refreshtoken"`
@ -1322,7 +1327,7 @@ func (q *Queries) DeletePrivilegeByID(ctx context.Context, id int32) error {
}
const deleteQuestion = `-- name: DeleteQuestion :one
UPDATE question SET deleted=true WHERE id=$1 RETURNING question.id, question.quiz_id, question.title, question.description, question.questiontype, question.required, question.deleted, question.page, question.content, question.version, question.parent_ids, question.created_at, question.updated_at
UPDATE question SET deleted=true WHERE id=$1 RETURNING question.id, question.quiz_id, question.title, question.description, question.questiontype, question.required, question.deleted, question.page, question.content, question.version, question.parent_ids, question.created_at, question.updated_at, question.session
`
func (q *Queries) DeleteQuestion(ctx context.Context, id int64) (Question, error) {
@ -1342,10 +1347,20 @@ func (q *Queries) DeleteQuestion(ctx context.Context, id int64) (Question, error
pq.Array(&i.ParentIds),
&i.CreatedAt,
&i.UpdatedAt,
&i.Session,
)
return i, err
}
const deleteQuizAudience = `-- name: DeleteQuizAudience :exec
UPDATE gigachatAudience set Deleted = TRUE WHERE QuizID = $1
`
func (q *Queries) DeleteQuizAudience(ctx context.Context, quizid int64) error {
_, err := q.db.ExecContext(ctx, deleteQuizAudience, quizid)
return err
}
const deleteQuizByID = `-- name: DeleteQuizByID :one
UPDATE quiz SET deleted=true WHERE quiz.id=$1 AND accountid=$2 RETURNING quiz.id, quiz.qid, quiz.accountid, quiz.deleted, quiz.archived, quiz.fingerprinting, quiz.repeatable, quiz.note_prevented, quiz.mail_notifications, quiz.unique_answers, quiz.super, quiz.group_id, quiz.name, quiz.description, quiz.config, quiz.status, quiz.limit_answers, quiz.due_to, quiz.time_of_passing, quiz.pausable, quiz.version, quiz.version_comment, quiz.parent_ids, quiz.created_at, quiz.updated_at, quiz.questions_count, quiz.answers_count, quiz.average_time_passing, quiz.sessions_count
`
@ -2493,11 +2508,25 @@ func (q *Queries) GetFieldByAmoID(ctx context.Context, amoid int32) (Field, erro
return i, err
}
const getFieldsCount = `-- name: GetFieldsCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM fields f JOIN user_data u ON f.AccountID = u.AmoID WHERE f.Deleted = false
`
func (q *Queries) GetFieldsCount(ctx context.Context, accountid string) (int64, error) {
row := q.db.QueryRowContext(ctx, getFieldsCount, accountid)
var count int64
err := row.Scan(&count)
return count, err
}
const getFieldsWithPagination = `-- name: GetFieldsWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT f.id, f.amoid, f.code, f.accountid, f.name, f.entity, f.type, f.deleted, f.createdat, COUNT(*) OVER() as total_count
SELECT f.id, f.amoid, f.code, f.accountid, f.name, f.entity, f.type, f.deleted, f.createdat
FROM fields f JOIN user_data u ON f.AccountID = u.AmoID
WHERE f.Deleted = false
ORDER BY f.ID OFFSET ($2 - 1) * $3 LIMIT $3
@ -2509,28 +2538,15 @@ type GetFieldsWithPaginationParams struct {
Limit int32 `db:"limit" json:"limit"`
}
type GetFieldsWithPaginationRow struct {
ID int64 `db:"id" json:"id"`
Amoid int32 `db:"amoid" json:"amoid"`
Code string `db:"code" json:"code"`
Accountid int32 `db:"accountid" json:"accountid"`
Name string `db:"name" json:"name"`
Entity interface{} `db:"entity" json:"entity"`
Type interface{} `db:"type" json:"type"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat sql.NullTime `db:"createdat" json:"createdat"`
TotalCount int64 `db:"total_count" json:"total_count"`
}
func (q *Queries) GetFieldsWithPagination(ctx context.Context, arg GetFieldsWithPaginationParams) ([]GetFieldsWithPaginationRow, error) {
func (q *Queries) GetFieldsWithPagination(ctx context.Context, arg GetFieldsWithPaginationParams) ([]Field, error) {
rows, err := q.db.QueryContext(ctx, getFieldsWithPagination, arg.Accountid, arg.Column2, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetFieldsWithPaginationRow
var items []Field
for rows.Next() {
var i GetFieldsWithPaginationRow
var i Field
if err := rows.Scan(
&i.ID,
&i.Amoid,
@ -2541,7 +2557,6 @@ func (q *Queries) GetFieldsWithPagination(ctx context.Context, arg GetFieldsWith
&i.Type,
&i.Deleted,
&i.Createdat,
&i.TotalCount,
); err != nil {
return nil, err
}
@ -2653,11 +2668,25 @@ func (q *Queries) GetListStartQuiz(ctx context.Context, accountid string) ([]int
return items, nil
}
const getPipelinesCount = `-- name: GetPipelinesCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM pipelines p JOIN user_data u ON p.AccountID = u.AmoID WHERE p.Deleted = false
`
func (q *Queries) GetPipelinesCount(ctx context.Context, accountid string) (int64, error) {
row := q.db.QueryRowContext(ctx, getPipelinesCount, accountid)
var count int64
err := row.Scan(&count)
return count, err
}
const getPipelinesWithPagination = `-- name: GetPipelinesWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT p.id, p.amoid, p.accountid, p.name, p.isarchive, p.deleted, p.createdat, COUNT(*) OVER() as total_count
SELECT p.id, p.amoid, p.accountid, p.name, p.isarchive, p.deleted, p.createdat
FROM pipelines p JOIN user_data u ON p.AccountID = u.AmoID
WHERE p.Deleted = false
ORDER BY p.ID OFFSET ($2 - 1) * $3 LIMIT $3
@ -2669,26 +2698,15 @@ type GetPipelinesWithPaginationParams struct {
Limit int32 `db:"limit" json:"limit"`
}
type GetPipelinesWithPaginationRow struct {
ID int64 `db:"id" json:"id"`
Amoid int32 `db:"amoid" json:"amoid"`
Accountid int32 `db:"accountid" json:"accountid"`
Name string `db:"name" json:"name"`
Isarchive bool `db:"isarchive" json:"isarchive"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat sql.NullTime `db:"createdat" json:"createdat"`
TotalCount int64 `db:"total_count" json:"total_count"`
}
func (q *Queries) GetPipelinesWithPagination(ctx context.Context, arg GetPipelinesWithPaginationParams) ([]GetPipelinesWithPaginationRow, error) {
func (q *Queries) GetPipelinesWithPagination(ctx context.Context, arg GetPipelinesWithPaginationParams) ([]Pipeline, error) {
rows, err := q.db.QueryContext(ctx, getPipelinesWithPagination, arg.Accountid, arg.Column2, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetPipelinesWithPaginationRow
var items []Pipeline
for rows.Next() {
var i GetPipelinesWithPaginationRow
var i Pipeline
if err := rows.Scan(
&i.ID,
&i.Amoid,
@ -2697,7 +2715,6 @@ func (q *Queries) GetPipelinesWithPagination(ctx context.Context, arg GetPipelin
&i.Isarchive,
&i.Deleted,
&i.Createdat,
&i.TotalCount,
); err != nil {
return nil, err
}
@ -2861,7 +2878,7 @@ func (q *Queries) GetQidOwner(ctx context.Context, qid uuid.NullUUID) (string, e
}
const getQuestionHistory = `-- name: GetQuestionHistory :many
SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at FROM question WHERE question.id = $1 OR question.id = ANY(
SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at, session FROM question WHERE question.id = $1 OR question.id = ANY(
SELECT unnest(parent_ids) FROM question WHERE id = $1
) ORDER BY question.id DESC LIMIT $2 OFFSET $3
`
@ -2895,6 +2912,7 @@ func (q *Queries) GetQuestionHistory(ctx context.Context, arg GetQuestionHistory
pq.Array(&i.ParentIds),
&i.CreatedAt,
&i.UpdatedAt,
&i.Session,
); err != nil {
return nil, err
}
@ -2910,7 +2928,7 @@ func (q *Queries) GetQuestionHistory(ctx context.Context, arg GetQuestionHistory
}
const getQuestionListByIDs = `-- name: GetQuestionListByIDs :many
SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at FROM question WHERE id = ANY($1::int[]) AND deleted = FALSE
SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at, session FROM question WHERE id = ANY($1::int[]) AND deleted = FALSE
`
func (q *Queries) GetQuestionListByIDs(ctx context.Context, dollar_1 []int32) ([]Question, error) {
@ -2936,6 +2954,7 @@ func (q *Queries) GetQuestionListByIDs(ctx context.Context, dollar_1 []int32) ([
pq.Array(&i.ParentIds),
&i.CreatedAt,
&i.UpdatedAt,
&i.Session,
); err != nil {
return nil, err
}
@ -2971,12 +2990,86 @@ const getQuestions = `-- name: GetQuestions :many
SELECT id, quiz_id, title, description, questiontype, required, deleted, page, content, version, parent_ids, created_at, updated_at FROM question WHERE quiz_id = $1 AND deleted = FALSE ORDER BY page ASC
`
func (q *Queries) GetQuestions(ctx context.Context, quizID int64) ([]Question, error) {
type GetQuestionsRow struct {
ID int64 `db:"id" json:"id"`
QuizID int64 `db:"quiz_id" json:"quiz_id"`
Title string `db:"title" json:"title"`
Description sql.NullString `db:"description" json:"description"`
Questiontype interface{} `db:"questiontype" json:"questiontype"`
Required sql.NullBool `db:"required" json:"required"`
Deleted sql.NullBool `db:"deleted" json:"deleted"`
Page sql.NullInt16 `db:"page" json:"page"`
Content sql.NullString `db:"content" json:"content"`
Version sql.NullInt16 `db:"version" json:"version"`
ParentIds []int32 `db:"parent_ids" json:"parent_ids"`
CreatedAt sql.NullTime `db:"created_at" json:"created_at"`
UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"`
}
func (q *Queries) GetQuestions(ctx context.Context, quizID int64) ([]GetQuestionsRow, error) {
rows, err := q.db.QueryContext(ctx, getQuestions, quizID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetQuestionsRow
for rows.Next() {
var i GetQuestionsRow
if err := rows.Scan(
&i.ID,
&i.QuizID,
&i.Title,
&i.Description,
&i.Questiontype,
&i.Required,
&i.Deleted,
&i.Page,
&i.Content,
&i.Version,
pq.Array(&i.ParentIds),
&i.CreatedAt,
&i.UpdatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getQuestionsAI = `-- name: GetQuestionsAI :many
SELECT q.id, q.quiz_id, q.title, q.description, q.questiontype, q.required, q.deleted, q.page, q.content, q.version, q.parent_ids, q.created_at, q.updated_at, q.session FROM question q
WHERE q.quiz_id = $1 AND (q.session = $2 OR q.session = '') AND q.deleted = FALSE
ORDER BY (q.session != '') ASC, --без сессии первые потом с сессией
q.page, --по возрастанию страницы
q.created_at --по времени создания
LIMIT $3 OFFSET $4
`
type GetQuestionsAIParams struct {
QuizID int64 `db:"quiz_id" json:"quiz_id"`
Session string `db:"session" json:"session"`
Limit int32 `db:"limit" json:"limit"`
Offset int32 `db:"offset" json:"offset"`
}
func (q *Queries) GetQuestionsAI(ctx context.Context, arg GetQuestionsAIParams) ([]Question, error) {
rows, err := q.db.QueryContext(ctx, getQuestionsAI,
arg.QuizID,
arg.Session,
arg.Limit,
arg.Offset,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Question
for rows.Next() {
var i Question
@ -2994,6 +3087,57 @@ func (q *Queries) GetQuestions(ctx context.Context, quizID int64) ([]Question, e
pq.Array(&i.ParentIds),
&i.CreatedAt,
&i.UpdatedAt,
&i.Session,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getQuestionsAICount = `-- name: GetQuestionsAICount :one
SELECT COUNT(*) AS count FROM question WHERE quiz_id = $1 AND (session = $2 OR session = '') AND deleted = FALSE
`
type GetQuestionsAICountParams struct {
QuizID int64 `db:"quiz_id" json:"quiz_id"`
Session string `db:"session" json:"session"`
}
func (q *Queries) GetQuestionsAICount(ctx context.Context, arg GetQuestionsAICountParams) (int64, error) {
row := q.db.QueryRowContext(ctx, getQuestionsAICount, arg.QuizID, arg.Session)
var count int64
err := row.Scan(&count)
return count, err
}
const getQuizAudience = `-- name: GetQuizAudience :many
SELECT id, quizid, sex, age, deleted, createdat FROM gigachatAudience WHERE QuizID = $1 AND Deleted = FALSE
`
func (q *Queries) GetQuizAudience(ctx context.Context, quizid int64) ([]Gigachataudience, error) {
rows, err := q.db.QueryContext(ctx, getQuizAudience, quizid)
if err != nil {
return nil, err
}
defer rows.Close()
var items []Gigachataudience
for rows.Next() {
var i Gigachataudience
if err := rows.Scan(
&i.ID,
&i.Quizid,
&i.Sex,
&i.Age,
&i.Deleted,
&i.Createdat,
); err != nil {
return nil, err
}
@ -3059,7 +3203,7 @@ SELECT id, qid, accountid, deleted, archived, fingerprinting, repeatable, note_p
WHERE
deleted = false AND
archived = false AND
status = 'start' AND
(status = 'start' OR status = 'ai') AND
qid = $1
`
@ -3188,11 +3332,16 @@ func (q *Queries) GetQuizHistory(ctx context.Context, arg GetQuizHistoryParams)
}
const getQuizRule = `-- name: GetQuizRule :one
SELECT id, accountid, quizid, performerid, pipelineid, stepid, fieldsrule, deleted, createdat, tagstoadd FROM rules WHERE QuizID = $1 AND Deleted = false
SELECT id, accountid, quizid, performerid, pipelineid, stepid, fieldsrule, deleted, createdat, tagstoadd FROM rules WHERE QuizID = $1 AND AccountID = (SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $2 AND accountsAmo.Deleted = false) AND Deleted = false
`
func (q *Queries) GetQuizRule(ctx context.Context, quizid int32) (Rule, error) {
row := q.db.QueryRowContext(ctx, getQuizRule, quizid)
type GetQuizRuleParams struct {
Quizid int32 `db:"quizid" json:"quizid"`
Accountid string `db:"accountid" json:"accountid"`
}
func (q *Queries) GetQuizRule(ctx context.Context, arg GetQuizRuleParams) (Rule, error) {
row := q.db.QueryRowContext(ctx, getQuizRule, arg.Quizid, arg.Accountid)
var i Rule
err := row.Scan(
&i.ID,
@ -3273,13 +3422,32 @@ func (q *Queries) GetResultAnswers(ctx context.Context, id int64) ([]GetResultAn
return items, nil
}
const getStepsCount = `-- name: GetStepsCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM steps s JOIN user_data u ON s.AccountID = u.AmoID WHERE s.Deleted = false AND s.PipelineID = $2
`
type GetStepsCountParams struct {
Accountid string `db:"accountid" json:"accountid"`
Pipelineid int32 `db:"pipelineid" json:"pipelineid"`
}
func (q *Queries) GetStepsCount(ctx context.Context, arg GetStepsCountParams) (int64, error) {
row := q.db.QueryRowContext(ctx, getStepsCount, arg.Accountid, arg.Pipelineid)
var count int64
err := row.Scan(&count)
return count, err
}
const getStepsWithPagination = `-- name: GetStepsWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT s.id, s.amoid, s.pipelineid, s.accountid, s.name, s.color, s.deleted, s.createdat, COUNT(*) OVER() as total_count
SELECT s.id, s.amoid, s.pipelineid, s.accountid, s.name, s.color, s.deleted, s.createdat
FROM steps s JOIN user_data u ON s.AccountID = u.AmoID
WHERE s.Deleted = false AND PipelineID = $4
WHERE s.Deleted = false AND s.PipelineID = $4
ORDER BY s.ID OFFSET ($2 - 1) * $3 LIMIT $3
`
@ -3290,19 +3458,7 @@ type GetStepsWithPaginationParams struct {
Pipelineid int32 `db:"pipelineid" json:"pipelineid"`
}
type GetStepsWithPaginationRow struct {
ID int64 `db:"id" json:"id"`
Amoid int32 `db:"amoid" json:"amoid"`
Pipelineid int32 `db:"pipelineid" json:"pipelineid"`
Accountid int32 `db:"accountid" json:"accountid"`
Name string `db:"name" json:"name"`
Color string `db:"color" json:"color"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat sql.NullTime `db:"createdat" json:"createdat"`
TotalCount int64 `db:"total_count" json:"total_count"`
}
func (q *Queries) GetStepsWithPagination(ctx context.Context, arg GetStepsWithPaginationParams) ([]GetStepsWithPaginationRow, error) {
func (q *Queries) GetStepsWithPagination(ctx context.Context, arg GetStepsWithPaginationParams) ([]Step, error) {
rows, err := q.db.QueryContext(ctx, getStepsWithPagination,
arg.Accountid,
arg.Column2,
@ -3313,9 +3469,9 @@ func (q *Queries) GetStepsWithPagination(ctx context.Context, arg GetStepsWithPa
return nil, err
}
defer rows.Close()
var items []GetStepsWithPaginationRow
var items []Step
for rows.Next() {
var i GetStepsWithPaginationRow
var i Step
if err := rows.Scan(
&i.ID,
&i.Amoid,
@ -3325,7 +3481,6 @@ func (q *Queries) GetStepsWithPagination(ctx context.Context, arg GetStepsWithPa
&i.Color,
&i.Deleted,
&i.Createdat,
&i.TotalCount,
); err != nil {
return nil, err
}
@ -3340,11 +3495,25 @@ func (q *Queries) GetStepsWithPagination(ctx context.Context, arg GetStepsWithPa
return items, nil
}
const getTagsCount = `-- name: GetTagsCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM tags t JOIN user_data u ON t.AccountID = u.AmoID WHERE t.Deleted = false
`
func (q *Queries) GetTagsCount(ctx context.Context, accountid string) (int64, error) {
row := q.db.QueryRowContext(ctx, getTagsCount, accountid)
var count int64
err := row.Scan(&count)
return count, err
}
const getTagsWithPagination = `-- name: GetTagsWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT t.id, t.amoid, t.accountid, t.entity, t.name, t.color, t.deleted, t.createdat, COUNT(*) OVER() as total_count
SELECT t.id, t.amoid, t.accountid, t.entity, t.name, t.color, t.deleted, t.createdat
FROM tags t JOIN user_data u ON t.AccountID = u.AmoID
WHERE t.Deleted = false
ORDER BY t.ID OFFSET ($2 - 1) * $3 LIMIT $3
@ -3356,27 +3525,15 @@ type GetTagsWithPaginationParams struct {
Limit int32 `db:"limit" json:"limit"`
}
type GetTagsWithPaginationRow struct {
ID int64 `db:"id" json:"id"`
Amoid int32 `db:"amoid" json:"amoid"`
Accountid int32 `db:"accountid" json:"accountid"`
Entity interface{} `db:"entity" json:"entity"`
Name string `db:"name" json:"name"`
Color string `db:"color" json:"color"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat sql.NullTime `db:"createdat" json:"createdat"`
TotalCount int64 `db:"total_count" json:"total_count"`
}
func (q *Queries) GetTagsWithPagination(ctx context.Context, arg GetTagsWithPaginationParams) ([]GetTagsWithPaginationRow, error) {
func (q *Queries) GetTagsWithPagination(ctx context.Context, arg GetTagsWithPaginationParams) ([]Tag, error) {
rows, err := q.db.QueryContext(ctx, getTagsWithPagination, arg.Accountid, arg.Column2, arg.Limit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetTagsWithPaginationRow
var items []Tag
for rows.Next() {
var i GetTagsWithPaginationRow
var i Tag
if err := rows.Scan(
&i.ID,
&i.Amoid,
@ -3386,7 +3543,6 @@ func (q *Queries) GetTagsWithPagination(ctx context.Context, arg GetTagsWithPagi
&i.Color,
&i.Deleted,
&i.Createdat,
&i.TotalCount,
); err != nil {
return nil, err
}
@ -3747,6 +3903,19 @@ func (q *Queries) GetUserUsersByID(ctx context.Context, amoid int32) ([]Usersamo
return items, nil
}
const getUsersCount = `-- name: GetUsersCount :one
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT COUNT(*) FROM usersAmo u JOIN user_data a ON u.AmoID = a.AmoID WHERE u.Deleted = false
`
func (q *Queries) GetUsersCount(ctx context.Context, accountid string) (int64, error) {
row := q.db.QueryRowContext(ctx, getUsersCount, accountid)
var count int64
err := row.Scan(&count)
return count, err
}
const getUserUsersByIDBitrix = `-- name: GetUserUsersByIDBitrix :many
SELECT id, accountid, bitrixiduserid, name, lastname, secondname, title, email, ufdepartment, workposition, deleted, createdat FROM BitrixAccountUsers WHERE accountID = $1 AND Deleted = false
`
@ -3859,11 +4028,12 @@ func (q *Queries) GetUsersBitrixWithPagination(ctx context.Context, arg GetUsers
return items, nil
}
const getUsersWithPagination = `-- name: GetUsersWithPagination :many
WITH user_data AS (
SELECT AmoID FROM accountsAmo WHERE accountsAmo.AccountID = $1 AND accountsAmo.Deleted = false
)
SELECT u.id, u.amoid, u.amouserid, u.name, u.email, u.role, u."Group", u.deleted, u.createdat, COUNT(*) OVER() as total_count
SELECT u.id, u.amoid, u.amouserid, u.name, u.email, u.role, u."Group", u.deleted, u.createdat
FROM usersAmo u
JOIN user_data a ON u.AmoID = a.AmoID
WHERE u.Deleted = false
@ -3876,20 +4046,7 @@ type GetUsersWithPaginationParams struct {
Limit int32 `db:"limit" json:"limit"`
}
type GetUsersWithPaginationRow struct {
ID int64 `db:"id" json:"id"`
Amoid int32 `db:"amoid" json:"amoid"`
Amouserid int32 `db:"amouserid" json:"amouserid"`
Name string `db:"name" json:"name"`
Email string `db:"email" json:"email"`
Role int32 `db:"role" json:"role"`
Group int32 `db:"Group" json:"Group"`
Deleted bool `db:"deleted" json:"deleted"`
Createdat time.Time `db:"createdat" json:"createdat"`
TotalCount int64 `db:"total_count" json:"total_count"`
}
func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPaginationParams) ([]GetUsersWithPaginationRow, error) {
func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPaginationParams) ([]Usersamo, error) {
rows, err := q.db.QueryContext(ctx, getUsersWithPagination, arg.Accountid, arg.Column2, arg.Limit)
if err != nil {
return nil, err
@ -3899,6 +4056,7 @@ func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPa
for rows.Next() {
var i GetUsersWithPaginationRow
if err := rows.Scan(
&i.QuizID,
&i.ID,
&i.Amoid,
&i.Amouserid,
@ -3925,11 +4083,11 @@ func (q *Queries) GetUsersWithPagination(ctx context.Context, arg GetUsersWithPa
const gettingAmoUsersTrueResults = `-- name: GettingAmoUsersTrueResults :many
SELECT a.quiz_id,a.id,a.result,a.question_id,a.content,a.session,
COALESCE((SELECT a2.utm
FROM answer a2
WHERE a2.start = true AND a2.session = a.session
LIMIT 1), '{}'::jsonb) AS utm
,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM usersAmo u WHERE u.AmoUserID = r.performerid AND u.deleted = false) AS performer_name,u.subdomain,u.accountid,u.driveurl
COALESCE((SELECT a2.utm
FROM answer a2
WHERE a2.start = true AND a2.session = a.session
LIMIT 1), '{}'::jsonb) AS utm
,t.accesstoken,r.accountid,r.fieldsrule,r.tagstoadd,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM usersAmo u WHERE u.AmoUserID = r.performerid AND u.amoid = r.accountid AND u.deleted = false) AS performer_name,u.subdomain,u.accountid,u.driveurl
FROM answer a
INNER JOIN quiz q ON a.quiz_id = q.id
LEFT JOIN amoCRMStatuses s ON a.id = s.AnswerID
@ -4246,10 +4404,11 @@ INSERT INTO question (
page,
content,
parent_ids,
updated_at
updated_at,
session
)
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9)
RETURNING id, created_at, updated_at
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)
RETURNING id, created_at, updated_at
`
type InsertQuestionParams struct {
@ -4262,6 +4421,7 @@ type InsertQuestionParams struct {
Content sql.NullString `db:"content" json:"content"`
ParentIds []int32 `db:"parent_ids" json:"parent_ids"`
UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"`
Session string `db:"session" json:"session"`
}
type InsertQuestionRow struct {
@ -4281,6 +4441,7 @@ func (q *Queries) InsertQuestion(ctx context.Context, arg InsertQuestionParams)
arg.Content,
pq.Array(arg.ParentIds),
arg.UpdatedAt,
arg.Session,
)
var i InsertQuestionRow
err := row.Scan(&i.ID, &i.CreatedAt, &i.UpdatedAt)
@ -4427,24 +4588,25 @@ func (q *Queries) MoveToHistoryQuiz(ctx context.Context, arg MoveToHistoryQuizPa
}
const questionsStatistics = `-- name: QuestionsStatistics :many
WITH Funnel AS (
WITH QuizAnswers AS (
SELECT
session, start, result, question_id, created_at, content, quiz_id
FROM answer
WHERE answer.quiz_id = $1 AND created_at between TO_TIMESTAMP($2)::timestamp and TO_TIMESTAMP($3)::timestamp
), QuizQuestions AS (SELECT title, page, id from question where quiz_id = $1), Funnel AS (
SELECT
COUNT(DISTINCT a.session) FILTER (WHERE a.start = FALSE) AS count_start_false,
COUNT(DISTINCT a.session) FILTER (WHERE a.start = TRUE) AS count_start_true,
COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN a.session END) AS count_f_result_with_t_question,
COUNT(DISTINCT a.session) FILTER (WHERE a.result = TRUE) AS count_t_result
FROM
answer a
QuizAnswers a
LEFT JOIN (
SELECT DISTINCT a.session, q.id AS qid_true_result
FROM answer a
FROM QuizAnswers a
JOIN question q ON a.question_id = q.id
WHERE a.result = TRUE AND a.quiz_id = $1
) AS q ON a.session = q.session
WHERE
a.quiz_id = $1
AND a.created_at >= TO_TIMESTAMP($2)
AND a.created_at <= TO_TIMESTAMP($3)
),
Results AS (
SELECT
@ -4453,30 +4615,32 @@ WITH Funnel AS (
CAST(COUNT(*) * 100.0 / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE) OVER (PARTITION BY a.quiz_id), 0) AS FLOAT8) AS percentage
FROM
question q
JOIN answer a ON q.id = a.question_id
LEFT JOIN QuizAnswers a ON q.id = a.question_id
WHERE
a.quiz_id = $1
AND a.created_at >= TO_TIMESTAMP($2)
AND a.created_at <= TO_TIMESTAMP($3)
AND a.result = TRUE
GROUP BY
q.title, a.quiz_id, a.result
q.title, a.result, a.quiz_id
HAVING
COUNT(*) >= 1
),
LastContent AS (
SELECT
a.question_id,
a.content AS last_answer_content
a.content AS last_answer_content,
a.result,
a.start
FROM
answer a
JOIN (
QuizAnswers a
LEFT JOIN (
SELECT
session,
question_id,
MAX(created_at) AS last_created_at
FROM
answer
QuizAnswers
WHERE
quiz_id = $1
AND start != true
@ -4484,7 +4648,9 @@ WITH Funnel AS (
AND created_at <= TO_TIMESTAMP($3)
GROUP BY
question_id, session
) AS last_created_at_one_session ON a.session = last_created_at_one_session.session AND a.question_id = last_created_at_one_session.question_id AND a.created_at = last_created_at_one_session.last_created_at
) AS last_created_at_one_session ON a.session = last_created_at_one_session.session
AND a.question_id = last_created_at_one_session.question_id
AND a.created_at = last_created_at_one_session.last_created_at
),
Questions AS (
SELECT
@ -4532,16 +4698,16 @@ type QuestionsStatisticsParams struct {
}
type QuestionsStatisticsRow struct {
CountStartFalse int64 `db:"count_start_false" json:"count_start_false"`
CountStartTrue int64 `db:"count_start_true" json:"count_start_true"`
CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"`
CountTResult int64 `db:"count_t_result" json:"count_t_result"`
ResultsTitle string `db:"results_title" json:"results_title"`
ResultsPercentage float64 `db:"results_percentage" json:"results_percentage"`
QuestionsTitle string `db:"questions_title" json:"questions_title"`
QuestionsPage int16 `db:"questions_page" json:"questions_page"`
AnswerContent string `db:"answer_content" json:"answer_content"`
QuestionsPercentage float64 `db:"questions_percentage" json:"questions_percentage"`
CountStartFalse int64 `db:"count_start_false" json:"count_start_false"`
CountStartTrue int64 `db:"count_start_true" json:"count_start_true"`
CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"`
CountTResult int64 `db:"count_t_result" json:"count_t_result"`
ResultsTitle string `db:"results_title" json:"results_title"`
ResultsPercentage float64 `db:"results_percentage" json:"results_percentage"`
QuestionsTitle string `db:"questions_title" json:"questions_title"`
QuestionsPage interface{} `db:"questions_page" json:"questions_page"`
AnswerContent string `db:"answer_content" json:"answer_content"`
QuestionsPercentage float64 `db:"questions_percentage" json:"questions_percentage"`
}
func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) {

49
model/gigachat.go Normal file

@ -0,0 +1,49 @@
package model
import (
"errors"
)
type GigaChatMessage struct {
Role string `json:"role"`
Content string `json:"content"`
}
type GigaChatRequest struct {
Model string `json:"model"`
Stream bool `json:"stream"`
UpdateInterval int `json:"update_interval"`
Messages []GigaChatMessage `json:"messages"`
}
type GigaChatResponse struct {
Choices []struct {
Message struct {
Role string `json:"role"`
Content string `json:"content"`
} `json:"message"`
} `json:"choices"`
}
const CreatePrompt = `Ты маркетолог и копирайтер. Твоя задача переформулировать маркетинговый вопрос так, чтобы он лучше подходил определённой целевой аудитории по полу и возрасту.
Ответ должен строго состоять из двух строк:
{
"title": "<переформулированный заголовок>",
"description": "<переформулированное описание>"
}
Я напишу возраст, пол, заголовок и описание вопроса, а ты вернёшь только отформатированный результат.`
var ReworkQuestionPrompt string = "%s %s пол.\n%s\n%s"
var EmptyResponseErrorGigaChat = errors.New("empty response from GigaChat try again")
type GigaChatAudience struct {
ID int64 `json:"id"`
QuizID int64 `json:"quiz_id"`
Sex bool `json:"sex"` // false - female, true - male
Age string `json:"age"`
Deleted bool `json:"deleted"`
CreatedAt int64 `json:"created_at"`
}

@ -13,6 +13,7 @@ const (
StatusStart = "start"
StatusTimeout = "timeout"
StatusOffLimit = "offlimit"
StatusAI = "ai"
TypeVariant = "variant"
TypeImages = "images"
@ -104,6 +105,8 @@ type Question struct {
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Session string `json:"session"`
}
// Answer record of question answer

@ -53,11 +53,15 @@ func (r *AmoRepository) GettingUserWithPagination(ctx context.Context, req *mode
Deleted: row.Deleted,
CreatedAt: row.Createdat,
}
count = row.TotalCount
users = append(users, user)
}
count, err = r.queries.GetUsersCount(ctx, accountID)
if err != nil {
return nil, err
}
resp := model.UserListResp{
Count: count,
Items: users,
@ -299,7 +303,6 @@ func (r *AmoRepository) GetPipelinesWithPagination(ctx context.Context, req *mod
var pipelines []model.Pipeline
for _, row := range rows {
count = row.TotalCount
pipeline := model.Pipeline{
ID: row.ID,
Amoid: row.Amoid,
@ -311,6 +314,11 @@ func (r *AmoRepository) GetPipelinesWithPagination(ctx context.Context, req *mod
pipelines = append(pipelines, pipeline)
}
count, err = r.queries.GetPipelinesCount(ctx, accountID)
if err != nil {
return nil, err
}
resp := model.UserListPipelinesResp{
Count: count,
Items: pipelines,
@ -400,7 +408,6 @@ func (r *AmoRepository) GetStepsWithPagination(ctx context.Context, req *model.P
var steps []model.Step
for _, row := range rows {
count = row.TotalCount
step := model.Step{
ID: row.ID,
Amoid: row.Amoid,
@ -413,6 +420,14 @@ func (r *AmoRepository) GetStepsWithPagination(ctx context.Context, req *model.P
steps = append(steps, step)
}
count, err = r.queries.GetStepsCount(ctx, sqlcgen.GetStepsCountParams{
Accountid: accountID,
Pipelineid: pipelineID,
})
if err != nil {
return nil, err
}
resp := model.UserListStepsResp{
Count: count,
Items: steps,
@ -505,8 +520,6 @@ func (r *AmoRepository) GetTagsWithPagination(ctx context.Context, req *model.Pa
var count int64
var tags []model.Tag
for _, row := range rows {
count = row.TotalCount
var entity model.EntityType
v := string(row.Entity.([]byte))
entity = model.EntityType(v)
@ -523,6 +536,11 @@ func (r *AmoRepository) GetTagsWithPagination(ctx context.Context, req *model.Pa
tags = append(tags, tag)
}
count, err = r.queries.GetTagsCount(ctx, accountID)
if err != nil {
return nil, err
}
resp := model.UserListTagsResp{
Count: count,
Items: tags,
@ -625,8 +643,6 @@ func (r *AmoRepository) GetFieldsWithPagination(ctx context.Context, req *model.
var fields []model.Field
for _, row := range rows {
count = row.TotalCount
var entity model.EntityType
v := string(row.Entity.([]byte))
entity = model.EntityType(v)
@ -649,6 +665,11 @@ func (r *AmoRepository) GetFieldsWithPagination(ctx context.Context, req *model.
fields = append(fields, field)
}
count, err = r.queries.GetFieldsCount(ctx, accountID)
if err != nil {
return nil, err
}
resp := model.UserListFieldsResp{
Count: count,
Items: fields,
@ -828,8 +849,11 @@ func (r *AmoRepository) SetQuizSettings(ctx context.Context, request *model.Rule
return nil
}
func (r *AmoRepository) GettingQuizRules(ctx context.Context, quizID int) (*model.Rule, error) {
row, err := r.queries.GetQuizRule(ctx, int32(quizID))
func (r *AmoRepository) GettingQuizRules(ctx context.Context, accountID string, quizID int) (*model.Rule, error) {
row, err := r.queries.GetQuizRule(ctx, sqlcgen.GetQuizRuleParams{
Quizid: int32(quizID),
Accountid: accountID,
})
if err != nil {
return nil, err
}

@ -43,6 +43,7 @@ func (r *QuestionRepository) CreateQuestion(ctx context.Context, record *model.Q
Content: sql.NullString{String: record.Content, Valid: true},
ParentIds: record.ParentIds,
UpdatedAt: sql.NullTime{Time: time.Now(), Valid: true},
Session: record.Session,
}
data, err := r.queries.InsertQuestion(ctx, params)
@ -159,6 +160,7 @@ func (r *QuestionRepository) GetQuestionList(
&pIds,
&piece.CreatedAt,
&piece.UpdatedAt,
&piece.Session,
); err != nil {
qerr = err
return
@ -489,6 +491,47 @@ func (r *QuestionRepository) GetQuestionListByIDs(ctx context.Context, ids []int
return questions, nil
}
func (r *QuestionRepository) GetQuestionsAI(ctx context.Context, quizID int64, session string, limit, offset int32) ([]model.Question, uint64, error) {
rows, err := r.queries.GetQuestionsAI(ctx, sqlcgen.GetQuestionsAIParams{
QuizID: quizID,
Session: session,
Limit: limit,
Offset: offset,
})
if err != nil {
return nil, 0, err
}
var questions []model.Question
var count int64
for _, row := range rows {
questions = append(questions, model.Question{
Id: uint64(row.ID),
QuizId: uint64(row.QuizID),
Title: row.Title,
Description: row.Description.String,
Type: string(row.Questiontype.([]byte)),
Required: row.Required.Bool,
Deleted: row.Deleted.Bool,
Page: int(row.Page.Int16),
Content: row.Content.String,
Version: int(row.Version.Int16),
ParentIds: row.ParentIds,
CreatedAt: row.CreatedAt.Time,
UpdatedAt: row.UpdatedAt.Time,
Session: row.Session,
})
}
count, err = r.queries.GetQuestionsAICount(ctx, sqlcgen.GetQuestionsAICountParams{
QuizID: quizID,
Session: session,
})
return questions, uint64(count), nil
}
func (r *QuestionRepository) CheckQuestionOwner(ctx context.Context, accountID string, questionID uint64) (bool, error) {
id, err := r.queries.CheckQuestionOwner(ctx, sqlcgen.CheckQuestionOwnerParams{
ID: int64(questionID),

@ -272,7 +272,7 @@ SELECT * FROM quiz
WHERE
deleted = false AND
archived = false AND
status = 'start' AND
(status = 'start' OR status = 'ai') AND
qid = $1;
`, qid)
if err != nil {
@ -662,6 +662,54 @@ func (r *QuizRepository) TemplateCopy(ctx context.Context, accountID, qID string
return quizID, nil
}
type DepsCreateQuizAudience struct {
QuizID int64 `json:"quiz_id"`
Sex bool `json:"sex"` // false - female, true - male
Age string `json:"age"`
}
func (r *QuizRepository) CreateQuizAudience(ctx context.Context, audience DepsCreateQuizAudience) (int64, error) {
result, err := r.queries.CreateQuizAudience(ctx, sqlcgen.CreateQuizAudienceParams{
Quizid: audience.QuizID,
Sex: audience.Sex,
Age: audience.Age,
})
if err != nil {
return 0, err
}
return result, nil
}
func (r *QuizRepository) GetQuizAudience(ctx context.Context, quizID int64) ([]model.GigaChatAudience, error) {
rows, err := r.queries.GetQuizAudience(ctx, quizID)
if err != nil {
return nil, err
}
var audiences []model.GigaChatAudience
for _, row := range rows {
audiences = append(audiences, model.GigaChatAudience{
ID: row.ID,
QuizID: row.ID,
Sex: row.Sex,
Age: row.Age,
Deleted: row.Deleted,
CreatedAt: row.Createdat.Time.Unix(),
})
}
return audiences, nil
}
func (r *QuizRepository) DeleteQuizAudience(ctx context.Context, quizID int64) error {
err := r.queries.DeleteQuizAudience(ctx, quizID)
if err != nil {
return err
}
return nil
}
func (r *QuizRepository) CheckQuizOwner(ctx context.Context, accountID string, quizID uint64) (bool, error) {
id, err := r.queries.CheckQuizOwner(ctx, sqlcgen.CheckQuizOwnerParams{
Accountid: accountID,

@ -143,6 +143,11 @@ FROM ordered_content a WHERE EXISTS (
queryParams = append(queryParams, reqExport.New)
}
mainQuery += ` AND EXISTS (
SELECT 1 FROM answer as a2
WHERE a2.session = a.session AND a2.result = TRUE AND a2.quiz_id = a.quiz_id
)`
mainQuery += ` ORDER BY a.session, a.question_id ASC, a.created_at DESC, a.result DESC`
rows, err := r.pool.QueryContext(ctx, mainQuery, queryParams...)

@ -0,0 +1,30 @@
package integration
import (
"context"
"fmt"
"gitea.pena/SQuiz/common/dal"
"testing"
)
func Test_GetQuestionList(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
d, err := dal.New(ctx, "host=localhost port=35432 user=squiz password=Redalert2 dbname=squiz sslmode=disable", nil)
if err != nil {
t.Fatal(err)
}
defer d.Close()
limit := int32(10)
offset := int32(1000)
list, count, err := d.QuestionRepo.GetQuestionsAI(ctx, 1308, "", limit, offset)
if err != nil {
t.Fatal(err)
}
fmt.Println(list)
fmt.Println(count)
}