Merge remote-tracking branch 'origin/amoCRM'
This commit is contained in:
commit
024f47a56d
67
dal/dal.go
67
dal/dal.go
@ -12,6 +12,7 @@ import (
|
||||
"github.com/minio/minio-go/v7"
|
||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/dal/sqlcgen"
|
||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/account"
|
||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/amo"
|
||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/answer"
|
||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/question"
|
||||
"penahub.gitlab.yandexcloud.net/backend/quiz/common.git/repository/quiz"
|
||||
@ -51,8 +52,8 @@ func New(ctx context.Context, cred string, minioClient *minio.Client) (*DAL, err
|
||||
queries := sqlcgen.New(pool)
|
||||
|
||||
accountRepo := account.NewAccountRepository(account.Deps{
|
||||
Queries: queries,
|
||||
Pool: pool,
|
||||
Queries: queries,
|
||||
Pool: pool,
|
||||
})
|
||||
|
||||
storerAnswer := &answer.StorerAnswer{}
|
||||
@ -130,3 +131,65 @@ func (d *DAL) Init() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmoDal struct {
|
||||
conn *sql.DB
|
||||
queries *sqlcgen.Queries
|
||||
AmoRepo *amo.AmoRepository
|
||||
QuestionRepo *question.QuestionRepository
|
||||
AnswerRepo *answer.AnswerRepository
|
||||
QuizRepo *quiz.QuizRepository
|
||||
}
|
||||
|
||||
func NewAmoDal(ctx context.Context, cred string) (*AmoDal, error) {
|
||||
pool, err := sql.Open("postgres", cred)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := pool.PingContext(timeoutCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
queries := sqlcgen.New(pool)
|
||||
|
||||
amoRepo := amo.NewAmoRepository(amo.Deps{
|
||||
Queries: queries,
|
||||
Pool: pool,
|
||||
})
|
||||
|
||||
questionRepo := question.NewQuestionRepository(question.Deps{
|
||||
Queries: queries,
|
||||
Pool: pool,
|
||||
})
|
||||
|
||||
answerRepo := answer.NewAnswerRepository(answer.Deps{
|
||||
Queries: queries,
|
||||
Pool: pool,
|
||||
})
|
||||
|
||||
quizRepo := quiz.NewQuizRepository(quiz.Deps{
|
||||
Queries: queries,
|
||||
Pool: pool,
|
||||
})
|
||||
|
||||
return &AmoDal{
|
||||
conn: pool,
|
||||
queries: queries,
|
||||
AmoRepo: amoRepo,
|
||||
QuestionRepo: questionRepo,
|
||||
AnswerRepo: answerRepo,
|
||||
QuizRepo: quizRepo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *AmoDal) Close(ctx context.Context) error {
|
||||
err := d.conn.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -670,3 +670,424 @@ SELECT cq.id AS quiz_id, q.title, q.description, q.questiontype, q.required, q.d
|
||||
FROM question q
|
||||
JOIN quiz old ON q.quiz_id = old.id
|
||||
JOIN copied_quiz cq ON old.qid = $2;
|
||||
|
||||
|
||||
-- amo methods:
|
||||
|
||||
-- name: CreateAmoAccount :exec
|
||||
INSERT INTO users (AccountID, AmoID, Name, Email, Role, "Group", Deleted, CreatedAt, Subdomain, AmoUserID, Country)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);
|
||||
|
||||
-- name: CreateWebHook :exec
|
||||
INSERT INTO tokens (AccountID, RefreshToken, AccessToken, AuthCode, Expiration, CreatedAt)
|
||||
VALUES ($1, $2, $3, $4, $5, $6);
|
||||
|
||||
-- name: WebhookUpdate :exec
|
||||
UPDATE tokens SET AccessToken = $1,RefreshToken = $2,Expiration = to_timestamp(($3)::bigint) AT TIME ZONE 'UTC' + INTERVAL '3 hours',CreatedAt = to_timestamp(($4)::bigint) AT TIME ZONE 'UTC' + INTERVAL '3 hours'
|
||||
WHERE accountID = $5;
|
||||
|
||||
-- name: GetAllTokens :many
|
||||
SELECT * FROM tokens;
|
||||
|
||||
-- name: CheckExpired :many
|
||||
SELECT * FROM tokens WHERE Expiration <= TO_TIMESTAMP(EXTRACT(EPOCH FROM NOW()) + (10 * 60));
|
||||
|
||||
-- name: WebhookDelete :exec
|
||||
WITH userd AS (
|
||||
UPDATE users SET Deleted = true WHERE AmoUserID = $1 RETURNING AccountID
|
||||
)
|
||||
DELETE FROM tokens WHERE AccountID IN (SELECT AccountID FROM userd);
|
||||
|
||||
-- name: SoftDeleteAccount :exec
|
||||
WITH userd AS (
|
||||
SELECT AmoUserID FROM users WHERE users.AccountID = $1
|
||||
),
|
||||
tokend AS (
|
||||
UPDATE users SET Deleted = true WHERE AmoUserID IN (SELECT AmoUserID FROM userd) RETURNING users.AccountID
|
||||
)
|
||||
DELETE FROM tokens WHERE tokens.AccountID IN (SELECT AccountID FROM tokend);
|
||||
|
||||
-- name: GetCurrentAccount :one
|
||||
SELECT * FROM users WHERE AccountID = $1;
|
||||
|
||||
-- name: CheckMainUser :exec
|
||||
UPDATE users SET Name = $1, "Group" = $2, Email = $3, Role = $4 WHERE AmoID = $5;
|
||||
|
||||
-- name: GetUsersWithPagination :many
|
||||
WITH user_data AS (
|
||||
SELECT AmoID FROM users WHERE users.AccountID = $1 AND Deleted = false
|
||||
)
|
||||
SELECT u.*, COUNT(*) OVER() as total_count
|
||||
FROM users u
|
||||
JOIN user_data a ON u.AmoUserID = a.AmoID
|
||||
WHERE u.Deleted = false
|
||||
ORDER BY u.ID OFFSET ($2 - 1) * $3 LIMIT $3;
|
||||
|
||||
-- name: GetTagsWithPagination :many
|
||||
SELECT t.*, COUNT(*) OVER() as total_count
|
||||
FROM tags t JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1) u ON t.AccountID = u.AmoID
|
||||
WHERE t.Deleted = false
|
||||
ORDER BY t.ID OFFSET ($2 - 1) * $3 LIMIT $3;
|
||||
|
||||
-- name: GetStepsWithPagination :many
|
||||
SELECT s.*, COUNT(*) OVER() as total_count
|
||||
FROM steps s JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1) u ON s.AccountID = u.AmoID
|
||||
WHERE s.Deleted = false
|
||||
ORDER BY s.ID OFFSET ($2 - 1) * $3 LIMIT $3;
|
||||
|
||||
-- name: GetPipelinesWithPagination :many
|
||||
SELECT p.*, COUNT(*) OVER() as total_count
|
||||
FROM pipelines p JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1) u ON p.AccountID = u.AmoID
|
||||
WHERE p.Deleted = false
|
||||
ORDER BY p.ID OFFSET ($2 - 1) * $3 LIMIT $3;
|
||||
|
||||
-- name: GetFieldsWithPagination :many
|
||||
SELECT f.*, COUNT(*) OVER() as total_count
|
||||
FROM fields f JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1) u ON f.AccountID = u.AmoID
|
||||
WHERE f.Deleted = false
|
||||
ORDER BY f.ID OFFSET ($2 - 1) * $3 LIMIT $3;
|
||||
|
||||
-- name: UpdateTags :exec
|
||||
UPDATE tags AS t
|
||||
SET name = (update_data ->> 'Name')::varchar(512),
|
||||
color = (update_data ->> 'Color')::varchar(50)
|
||||
FROM json_array_elements($1::json) AS update_data
|
||||
WHERE t.amoID = (update_data ->> 'AmoID')::INT
|
||||
AND t.accountID = (update_data ->> 'AccountID')::INT
|
||||
AND t.Entity = (update_data ->> 'Entity')::entitytype;
|
||||
|
||||
-- name: UpdatePipelines :exec
|
||||
UPDATE pipelines AS p
|
||||
SET name = (update_data ->> 'Name')::varchar(512),
|
||||
isArchive = CASE WHEN (update_data ->> 'IsArchive') = 'true' THEN TRUE ELSE FALSE END
|
||||
FROM json_array_elements($1::json) AS update_data
|
||||
WHERE p.amoID = (update_data ->> 'AmoID')::INT
|
||||
AND p.accountID = (update_data ->> 'AccountID')::INT;
|
||||
|
||||
-- name: UpdateSteps :exec
|
||||
UPDATE steps AS s
|
||||
SET name = (update_data ->> 'Name')::varchar(512),
|
||||
color = (update_data ->> 'Color')::varchar(50)
|
||||
FROM json_array_elements($1::json) AS update_data
|
||||
WHERE s.amoID = (update_data ->> 'AmoID')::INT
|
||||
AND s.accountID = (update_data ->> 'AccountID')::INT
|
||||
AND s.pipelineID = (update_data ->> 'PipelineID')::INT;
|
||||
|
||||
-- name: UpdateFields :exec
|
||||
UPDATE fields AS f
|
||||
SET name = (update_data ->> 'Name')::varchar(512),
|
||||
code = (update_data ->> 'Code')::varchar(255),
|
||||
type = (update_data ->> 'Type')::fieldtype
|
||||
FROM json_array_elements($1::json) AS update_data
|
||||
WHERE f.amoID = (update_data ->> 'AmoID')::INT
|
||||
AND f.accountID = (update_data ->> 'AccountID')::INT
|
||||
AND f.Entity = (update_data ->> 'Entity')::entitytype;
|
||||
|
||||
-- name: CheckTags :many
|
||||
WITH user_data AS (
|
||||
SELECT AmoID
|
||||
FROM users
|
||||
WHERE users.AccountID = $1
|
||||
), new_tags AS (
|
||||
SELECT (tag->>'AmoID')::INT AS amoID,
|
||||
(tag->>'Entity')::entitytype AS Entity,
|
||||
COALESCE(tag->>'Name', '')::VARCHAR(512) AS name,
|
||||
COALESCE(tag->>'Color', '')::VARCHAR(50) AS color
|
||||
FROM json_array_elements($2::json) AS tag
|
||||
), inserted_tags AS (
|
||||
INSERT INTO tags (amoID, accountID, Entity, name, color, createdAt)
|
||||
SELECT nt.amoID,
|
||||
ud.AmoID,
|
||||
nt.Entity,
|
||||
nt.name,
|
||||
nt.color,
|
||||
CURRENT_TIMESTAMP
|
||||
FROM new_tags nt
|
||||
JOIN user_data ud ON true
|
||||
ON CONFLICT (amoID, accountID, Entity) DO NOTHING
|
||||
RETURNING *
|
||||
)
|
||||
SELECT nt.*,ud.AmoID
|
||||
FROM new_tags nt
|
||||
JOIN user_data ud ON true
|
||||
WHERE NOT EXISTS (
|
||||
SELECT *
|
||||
FROM inserted_tags ins
|
||||
JOIN user_data ud ON true
|
||||
WHERE ins.amoID = nt.amoID AND ins.accountID = ud.amoid AND ins.Entity = nt.Entity
|
||||
);
|
||||
|
||||
-- name: CheckPipelines :many
|
||||
WITH new_pipelines AS (
|
||||
SELECT (pipeline->>'AmoID')::INT AS amoID,
|
||||
(pipeline->>'AccountID')::INT AS accountID,
|
||||
COALESCE(pipeline->>'Name', '')::varchar(512) AS name,
|
||||
CASE WHEN (pipeline->>'IsArchive') = 'true' THEN TRUE ELSE FALSE END AS isArchive,
|
||||
CURRENT_TIMESTAMP AS createdAt
|
||||
FROM json_array_elements($1::json) AS pipeline
|
||||
), inserted_pipelines AS(
|
||||
INSERT INTO pipelines (amoID, accountID, name, isArchive, createdAt)
|
||||
SELECT np.amoID,
|
||||
np.accountID,
|
||||
np.name,
|
||||
np.isArchive,
|
||||
np.createdAt
|
||||
FROM new_pipelines np
|
||||
ON CONFLICT (amoID, accountID) DO NOTHING
|
||||
RETURNING *
|
||||
)
|
||||
SELECT np.*
|
||||
FROM new_pipelines np
|
||||
WHERE NOT EXISTS (
|
||||
SELECT *
|
||||
FROM inserted_pipelines ins
|
||||
WHERE ins.amoID = np.amoID AND ins.accountID = np.accountID
|
||||
);
|
||||
|
||||
-- name: CheckFields :many
|
||||
WITH user_data AS (
|
||||
SELECT AmoID
|
||||
FROM users
|
||||
WHERE users.AccountID = $1
|
||||
), new_fields AS (
|
||||
SELECT (field->>'AmoID')::INT AS amoID,
|
||||
COALESCE(field->>'Code', '')::varchar(255) AS code,
|
||||
COALESCE(field->>'Name', '')::varchar(512) AS name,
|
||||
CAST(field->>'Entity' AS entitytype) AS Entity,
|
||||
COALESCE(field->>'Type', '')::fieldtype AS type,
|
||||
CURRENT_TIMESTAMP AS createdAt
|
||||
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.*,ud.AmoID
|
||||
FROM new_fields nf
|
||||
JOIN user_data ud ON true
|
||||
WHERE NOT EXISTS (
|
||||
SELECT *
|
||||
FROM inserted_fields ins
|
||||
JOIN user_data ud ON true
|
||||
WHERE ins.amoID = nf.amoID AND ins.accountID = ud.amoid AND ins.Entity = nf.Entity
|
||||
);
|
||||
|
||||
-- name: CheckSteps :many
|
||||
WITH new_steps AS (
|
||||
SELECT (step->>'AmoID')::INT AS amoID,
|
||||
(step->>'PipelineID')::INT AS pipelineID,
|
||||
(step->>'AccountID')::INT AS accountID,
|
||||
COALESCE(step->>'Name', '')::varchar(512) AS name,
|
||||
COALESCE(step->>'Color', '')::varchar(50) AS color,
|
||||
CURRENT_TIMESTAMP AS createdAt
|
||||
FROM json_array_elements($1::json) AS step
|
||||
), inserted_steps AS (
|
||||
INSERT INTO steps (amoID, pipelineID, accountID, name, color, createdAt)
|
||||
SELECT ns.amoID,
|
||||
ns.pipelineID,
|
||||
ns.accountID,
|
||||
ns.name,
|
||||
ns.color,
|
||||
ns.createdAt
|
||||
FROM new_steps ns
|
||||
ON CONFLICT (amoID, accountID, PipelineID) DO NOTHING
|
||||
RETURNING *
|
||||
)
|
||||
SELECT ns.*
|
||||
FROM new_steps ns
|
||||
WHERE NOT EXISTS (
|
||||
SELECT *
|
||||
FROM inserted_steps ins
|
||||
WHERE ins.amoID = ns.amoID AND ins.accountID = ns.accountID AND ins.pipelineID = ns.pipelineID
|
||||
);
|
||||
|
||||
-- name: GetTokenById :one
|
||||
SELECT * FROM tokens WHERE accountID = $1;
|
||||
|
||||
-- name: DeletingUTM :exec
|
||||
UPDATE utms SET Deleted = true WHERE ID = ANY($1::int[]);
|
||||
|
||||
-- name: GetUTMsWithPagination :many
|
||||
SELECT ut.*, COUNT(*) OVER() as total_count
|
||||
FROM utms ut JOIN (SELECT AmoID FROM users WHERE users.AccountID = $1) u ON ut.AccountID = u.AmoID
|
||||
WHERE ut.Deleted = false and ut.QuizID = $4
|
||||
ORDER BY ut.ID OFFSET ($2 - 1) * $3 LIMIT $3;
|
||||
|
||||
-- name: SaveUTMs :many
|
||||
WITH user_data AS (
|
||||
SELECT AmoID
|
||||
FROM users
|
||||
WHERE users.AccountID = $1
|
||||
), new_UTMs AS (
|
||||
SELECT (utm->>'AmoFieldID')::INT AS amoFieldID,
|
||||
COALESCE(utm->>'QuizID', '')::INT AS quizID,
|
||||
COALESCE(utm->>'Name', '')::varchar(512) AS name,
|
||||
CURRENT_TIMESTAMP AS createdAt
|
||||
FROM json_array_elements($2::json) AS utm
|
||||
), inserted_utms AS(
|
||||
INSERT INTO utms (AmoFieldID, QuizID, AccountID, Name, createdAt)
|
||||
SELECT nu.amoFieldID,
|
||||
nu.quizID,
|
||||
ud.AmoID,
|
||||
nu.name,
|
||||
nu.createdAt
|
||||
FROM new_UTMs nu
|
||||
JOIN user_data ud ON true
|
||||
RETURNING *
|
||||
)
|
||||
SELECT * from inserted_utms;
|
||||
|
||||
-- name: GetQuizRule :one
|
||||
SELECT * FROM rules WHERE QuizID = $1 AND Deleted = false;
|
||||
|
||||
-- name: SetQuizSettings :exec
|
||||
INSERT INTO rules (AccountID, QuizID, PerformerID, PipelineID, StepID, UTMS, FieldsRule)
|
||||
SELECT u.AmoID AS AccountID,$1 AS QuizID,$2 AS PerformerID,$3 AS PipelineID,
|
||||
$4 AS StepID,$5 AS UTMS,$6 AS FieldsRule FROM users u WHERE u.AccountID = $7;
|
||||
|
||||
-- name: ChangeQuizSettings :exec
|
||||
UPDATE rules
|
||||
SET PerformerID = $1,PipelineID = $2,StepID = $3,UTMS = $4,FieldsRule = $5
|
||||
WHERE AccountID = (SELECT AmoID FROM users WHERE users.AccountID = $6) AND QuizID = $7 AND Deleted = false;
|
||||
|
||||
-- name: GetUtmsByID :many
|
||||
SELECT ID,AmoFieldID,QuizID,AccountID,Name
|
||||
FROM utms
|
||||
WHERE
|
||||
ID = ANY($1::int[]) AND Deleted = FALSE;
|
||||
|
||||
-- name: GetUserFieldsByID :many
|
||||
SELECT ID,AmoID,Code,AccountID,Name,Entity,Type
|
||||
FROM fields
|
||||
WHERE AccountID = $1 AND Deleted = false;
|
||||
|
||||
-- name: UpdateUtms :exec
|
||||
UPDATE utms AS u
|
||||
SET name = (update_data ->> 'Name')::varchar(512),
|
||||
AmoFieldID = (update_data ->> 'AmoFieldID')::INT
|
||||
FROM json_array_elements($1::json) AS update_data
|
||||
WHERE u.ID = (update_data ->> 'ID')::INT;
|
||||
|
||||
-- name: UpdateUtmsFields :exec
|
||||
UPDATE utms AS u SET AmoFieldID = f.AmoID FROM fields AS f
|
||||
WHERE u.Name = f.Name AND u.ID = ANY($1::int[]) AND u.Deleted = FALSE;
|
||||
|
||||
-- name: GetQuestionListByIDs :many
|
||||
SELECT * FROM question WHERE id = ANY($1::int[]) AND deleted = FALSE;
|
||||
|
||||
-- name: UpdateFieldRules :exec
|
||||
UPDATE rules SET FieldsRule = $1
|
||||
WHERE AccountID = (SELECT AmoID FROM users WHERE users.AccountID = $2) AND QuizID = $3 AND Deleted = false;
|
||||
|
||||
-- name: UpdateUsers :exec
|
||||
UPDATE users AS u
|
||||
SET Name = (update_data ->> 'Name')::varchar(512),
|
||||
Email = (update_data ->> 'Email')::varchar(50),
|
||||
Role = (update_data ->> 'Role')::INT,
|
||||
"Group" = (update_data ->> 'Group')::INT,
|
||||
AmoUserID= (update_data ->> 'AmoUserID')::INT
|
||||
FROM json_array_elements($1::json) AS update_data
|
||||
WHERE u.AmoID = (update_data ->> 'AmocrmID')::INT;
|
||||
|
||||
-- name: CheckUsers :many
|
||||
WITH new_users AS (
|
||||
SELECT (u->>'AmocrmID')::INT AS AmoID,
|
||||
(u->>'Name')::VARCHAR(512) AS Name,
|
||||
(u->>'Group')::INT AS "Group",
|
||||
(u->>'Role')::INT AS Role,
|
||||
(u->>'Email')::VARCHAR(50) AS Email,
|
||||
(u->>'AmoUserID')::INT AS AmoUserID,
|
||||
CURRENT_TIMESTAMP AS createdAt
|
||||
FROM json_array_elements($1::json) AS u
|
||||
), inserted_users AS (
|
||||
INSERT INTO users (AmoID, Name, "Group", Role, Email, AmoUserID,createdAt)
|
||||
SELECT nu.AmoID,
|
||||
nu.Name,
|
||||
nu."Group",
|
||||
nu.Role,
|
||||
nu.Email,
|
||||
nu.AmoUserID,
|
||||
nu.createdAt
|
||||
FROM new_users nu
|
||||
ON CONFLICT (amoID) DO NOTHING
|
||||
RETURNING *
|
||||
)
|
||||
SELECT nu.*
|
||||
FROM new_users nu
|
||||
WHERE NOT EXISTS (
|
||||
SELECT *
|
||||
FROM inserted_users ins
|
||||
WHERE ins.amoID = nu.amoID
|
||||
);
|
||||
|
||||
-- name: GettingAmoUsersTrueResults :many
|
||||
SELECT a.quiz_id,a.id,a.result,a.question_id,a.content,a.session,t.accesstoken,r.accountid,r.utms,r.fieldsrule,r.performerid,r.stepid,r.pipelineid,(SELECT u.name FROM users u WHERE u.amoid = r.performerid) AS performer_name
|
||||
FROM answer a
|
||||
INNER JOIN quiz q ON a.quiz_id = q.id
|
||||
LEFT JOIN amoCRMStatuses s ON a.id = s.AnswerID
|
||||
INNER JOIN rules r ON q.id = r.QuizID
|
||||
INNER JOIN tokens t ON q.accountid = t.AccountID
|
||||
INNER JOIN users u ON q.accountid = u.accountid AND u.amoid = r.accountid
|
||||
WHERE a.result = true
|
||||
AND s.id IS NULL
|
||||
AND a.deleted = false
|
||||
AND r.deleted = false
|
||||
AND q.deleted = false;
|
||||
|
||||
-- name: SettingDealAmoStatus :exec
|
||||
INSERT INTO amoCRMStatuses (AccountID, DealID, AnswerID, Status)
|
||||
SELECT u.AmoID, $1, $2, $3
|
||||
FROM tokens AS t
|
||||
JOIN users AS u ON t.AccountID = u.AccountID
|
||||
WHERE t.AccessToken = $4;
|
||||
|
||||
-- name: UpdatingDealAmoStatus :exec
|
||||
UPDATE amoCRMStatuses SET Status = $1
|
||||
WHERE DealID = $2 AND AccountID = (SELECT u.AmoID FROM tokens AS t JOIN users AS u ON t.AccountID = u.AccountID WHERE t.AccessToken = $3);
|
||||
|
||||
-- name: DeleteFields :exec
|
||||
UPDATE fields SET Deleted = true WHERE ID = ANY($1::bigint[]);
|
||||
|
||||
-- name: DeleteTags :exec
|
||||
UPDATE tags SET Deleted = true WHERE ID = ANY($1::bigint[]);
|
||||
|
||||
-- name: DeleteSteps :exec
|
||||
UPDATE steps SET Deleted = true WHERE ID = ANY($1::bigint[]);
|
||||
|
||||
-- name: DeletePipelines :exec
|
||||
UPDATE pipelines SET Deleted = true WHERE ID = ANY($1::bigint[]);
|
||||
|
||||
-- name: DeleteUsers :exec
|
||||
UPDATE users SET Deleted = true WHERE ID = ANY($1::bigint[]);
|
||||
|
||||
-- name: GetUserTagsByID :many
|
||||
SELECT ID,AmoID,AccountID,Name,Entity,Color
|
||||
FROM tags
|
||||
WHERE AccountID = $1 AND Deleted = false;
|
||||
|
||||
-- name: GetUserStepsByID :many
|
||||
SELECT ID,AmoID,PipelineID,AccountID,Name,Color
|
||||
FROM steps
|
||||
WHERE AccountID = $1 AND Deleted = false;
|
||||
|
||||
-- name: GetUserPipelinesByID :many
|
||||
SELECT ID,AmoID,AccountID,Name,IsArchive
|
||||
FROM pipelines
|
||||
WHERE AccountID = $1 AND Deleted = false;
|
||||
|
||||
-- name: GetUserUsersByID :many
|
||||
SELECT ID,AccountID,AmoID,Name,Email,Role,"Group",Subdomain,AmoUserID,Country
|
||||
FROM users
|
||||
WHERE AmoUserID = $1 AND Deleted = false;
|
||||
|
||||
-- name: GetFieldByAmoID :one
|
||||
SELECT * FROM fields WHERE AmoID = $1 AND Deleted = false;
|
||||
|
31
dal/schema/000010_init.down.sql
Normal file
31
dal/schema/000010_init.down.sql
Normal file
@ -0,0 +1,31 @@
|
||||
DROP INDEX IF EXISTS idx_unique_users;
|
||||
DROP INDEX IF EXISTS idx_unique_pipeline;
|
||||
DROP INDEX IF EXISTS idx_unique_step;
|
||||
DROP INDEX IF EXISTS idx_unique_field;
|
||||
DROP INDEX IF EXISTS idx_unique_tag;
|
||||
DROP INDEX IF EXISTS idx_unique_rules;
|
||||
|
||||
DROP TABLE IF EXISTS amoCRMStatuses;
|
||||
DROP TABLE IF EXISTS rules;
|
||||
DROP TABLE IF EXISTS utms;
|
||||
DROP TABLE IF EXISTS tags;
|
||||
DROP TABLE IF EXISTS fields;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'entitytype') THEN
|
||||
DROP TYPE EntityType;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (SELECT 1 FROM pg_type WHERE typname = 'fieldtype') THEN
|
||||
DROP TYPE FieldType;
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DROP TABLE IF EXISTS steps;
|
||||
DROP TABLE IF EXISTS pipelines;
|
||||
DROP TABLE IF EXISTS tokens;
|
||||
DROP TABLE IF EXISTS users;
|
119
dal/schema/000010_init.up.sql
Normal file
119
dal/schema/000010_init.up.sql
Normal file
@ -0,0 +1,119 @@
|
||||
CREATE TABLE IF NOT EXISTS tokens (
|
||||
AccountID VARCHAR(30) PRIMARY KEY, -- связь с users AccountID неявная посредством join
|
||||
RefreshToken TEXT NOT NULL ,
|
||||
AccessToken TEXT NOT NULL ,
|
||||
AuthCode TEXT NOT NULL , -- код авторизации который получаем при вебхук
|
||||
Expiration TIMESTAMP NOT NULL, -- время истечения токенов
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AccountID VARCHAR(30) NOT NULL DEFAULT '', -- id квизе из токена
|
||||
AmoID INT NOT NULL , -- id в амо
|
||||
Name VARCHAR(512) NOT NULL DEFAULT '', -- имя в амо
|
||||
Email VARCHAR(50) NOT NULL DEFAULT '', -- почта в амо
|
||||
Role INT NOT NULL DEFAULT 0, -- роль в амо
|
||||
"Group" INT NOT NULL DEFAULT 0, -- вложенная структура так как в амо группы хранятся массивом структур
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
Subdomain VARCHAR(50) NOT NULL DEFAULT '',
|
||||
AmoUserID INT NOT NULL , -- id пользователя который подключал интеграцию
|
||||
Country VARCHAR(50) NOT NULL DEFAULT '' -- страна в амо
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pipelines (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AmoID INT NOT NULL , --id воронки в амо
|
||||
AccountID INT NOT NULL , --id аккаунта в амо связь с таблицей users AmoID неявная посредством join
|
||||
Name VARCHAR(512) NOT NULL DEFAULT '', --название воронки в амо
|
||||
IsArchive BOOLEAN NOT NULL DEFAULT FALSE, --флаг архивной воронки в амо
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS steps (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AmoID INT NOT NULL, --id шага воронки в амо
|
||||
PipelineID INT NOT NULL, --id воронки AmoID pipelines неявная посредством join
|
||||
AccountID INT NOT NULL, --id аккаунта в амо связь с таблицей users AmoID неявная посредством join
|
||||
Name VARCHAR(512) NOT NULL DEFAULT '', --название воронки в амо
|
||||
Color VARCHAR(50) NOT NULL DEFAULT '', --цвет шага в амо*
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'entitytype') THEN
|
||||
CREATE TYPE EntityType AS ENUM ('leads', 'contacts', 'companies', 'customers');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'fieldtype') THEN
|
||||
CREATE TYPE FieldType AS ENUM ('text', 'numeric', 'checkbox', 'select', 'multiselect', 'date', 'url', 'textarea', 'radiobutton', 'streetaddress', 'smart_address', 'birthday', 'legal_entity', 'date_time', 'price', 'category', 'items', 'tracking_data', 'linked_entity', 'chained_list', 'monetary', 'file', 'payer', 'supplier', 'multitext');
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fields (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AmoID INT NOT NULL, -- айдишник кастомного поля в амо
|
||||
Code VARCHAR(255) NOT NULL DEFAULT '', -- кодовое слово в амо
|
||||
AccountID INT NOT NULL, -- id аккаунта в амо связь с таблицей users AmoID неявная посредством join
|
||||
Name VARCHAR(512) NOT NULL DEFAULT '', -- название воронки в амо
|
||||
Entity EntityType NOT NULL, -- тип сущности в амо, для которой это кастомное поле
|
||||
Type FieldType NOT NULL, -- тип поля
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS tags (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AmoID INT NOT NULL, -- айдишник тега в амо
|
||||
AccountID INT NOT NULL, -- id аккаунта в амо связь с таблицей users AmoID неявная посредством join
|
||||
Entity EntityType NOT NULL, -- сущность, к которой принадлежит этот тег
|
||||
Name VARCHAR(512) NOT NULL DEFAULT '', -- название тега в амо
|
||||
Color VARCHAR(50) NOT NULL DEFAULT '', -- цвет тега в амо
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS utms (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AmoFieldID INT NOT NULL DEFAULT 0, -- id field в амо
|
||||
QuizID INT NOT NULL, -- id опроса
|
||||
AccountID INT NOT NULL, -- id аккаунта в амо AMOID
|
||||
Name VARCHAR(512) NOT NULL DEFAULT '', -- название utm
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS rules (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AccountID INT NOT NULL, -- id аккаунта в амо AMOID
|
||||
QuizID INT NOT NULL, -- id опроса
|
||||
PerformerID INT NOT NULL, -- айдишник ответственного за сделку
|
||||
PipelineID INT NOT NULL, --id воронки AmoID pipelines неявная посредством join
|
||||
StepID INT NOT NULL , -- id этапа steps AmoID join
|
||||
UTMS INTEGER[], -- список UTM для этого опроса id utm
|
||||
FieldsRule JSONB NOT NULL DEFAULT '{}', -- вложенная структура
|
||||
Deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_unique_users ON users (amoID);
|
||||
CREATE UNIQUE INDEX idx_unique_pipeline ON pipelines (amoID, accountID);
|
||||
CREATE UNIQUE INDEX idx_unique_step ON steps (amoID, accountID, PipelineID);
|
||||
CREATE UNIQUE INDEX idx_unique_field ON fields (amoID, accountID, entity);
|
||||
CREATE UNIQUE INDEX idx_unique_tag ON tags (amoID, accountID, entity);
|
||||
CREATE UNIQUE INDEX idx_unique_rules ON rules (accountID, QuizID);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS amoCRMStatuses (
|
||||
ID BIGSERIAL UNIQUE NOT NULL PRIMARY KEY,
|
||||
AccountID INT NOT NULL, -- id аккаунта в амо
|
||||
DealID INT NOT NULL, -- id сделки в которую добавлялось
|
||||
AnswerID BIGINT NOT NULL REFERENCES answer(id), -- id true result который вызвал действие
|
||||
Status TEXT NOT NULL DEFAULT '', -- запись о ошибке, либо успехе
|
||||
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
@ -1,6 +1,6 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.26.0
|
||||
// sqlc v1.25.0
|
||||
|
||||
package sqlcgen
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.26.0
|
||||
// sqlc v1.25.0
|
||||
|
||||
package sqlcgen
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@ -18,6 +20,15 @@ type Account struct {
|
||||
Deleted sql.NullBool `db:"deleted" json:"deleted"`
|
||||
}
|
||||
|
||||
type Amocrmstatus struct {
|
||||
ID int64 `db:"id" json:"id"`
|
||||
Accountid int32 `db:"accountid" json:"accountid"`
|
||||
Dealid int32 `db:"dealid" json:"dealid"`
|
||||
Answerid int64 `db:"answerid" json:"answerid"`
|
||||
Status string `db:"status" json:"status"`
|
||||
Createdat sql.NullTime `db:"createdat" json:"createdat"`
|
||||
}
|
||||
|
||||
type Answer struct {
|
||||
ID int64 `db:"id" json:"id"`
|
||||
Content sql.NullString `db:"content" json:"content"`
|
||||
@ -38,6 +49,28 @@ type Answer struct {
|
||||
Start bool `db:"start" json:"start"`
|
||||
}
|
||||
|
||||
type Field 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"`
|
||||
}
|
||||
|
||||
type Pipeline 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"`
|
||||
}
|
||||
|
||||
type Privilege struct {
|
||||
ID int32 `db:"id" json:"id"`
|
||||
Privilegeid sql.NullString `db:"privilegeid" json:"privilegeid"`
|
||||
@ -94,3 +127,72 @@ type Quiz struct {
|
||||
AverageTimePassing sql.NullInt32 `db:"average_time_passing" json:"average_time_passing"`
|
||||
SessionsCount sql.NullInt32 `db:"sessions_count" json:"sessions_count"`
|
||||
}
|
||||
|
||||
type Rule struct {
|
||||
ID int64 `db:"id" json:"id"`
|
||||
Accountid int32 `db:"accountid" json:"accountid"`
|
||||
Quizid int32 `db:"quizid" json:"quizid"`
|
||||
Performerid int32 `db:"performerid" json:"performerid"`
|
||||
Pipelineid int32 `db:"pipelineid" json:"pipelineid"`
|
||||
Stepid int32 `db:"stepid" json:"stepid"`
|
||||
Utms []int32 `db:"utms" json:"utms"`
|
||||
Fieldsrule json.RawMessage `db:"fieldsrule" json:"fieldsrule"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Createdat sql.NullTime `db:"createdat" json:"createdat"`
|
||||
}
|
||||
|
||||
type Step 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"`
|
||||
}
|
||||
|
||||
type Tag 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"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Accountid string `db:"accountid" json:"accountid"`
|
||||
Refreshtoken string `db:"refreshtoken" json:"refreshtoken"`
|
||||
Accesstoken string `db:"accesstoken" json:"accesstoken"`
|
||||
Authcode string `db:"authcode" json:"authcode"`
|
||||
Expiration time.Time `db:"expiration" json:"expiration"`
|
||||
Createdat sql.NullTime `db:"createdat" json:"createdat"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID int64 `db:"id" json:"id"`
|
||||
Accountid string `db:"accountid" json:"accountid"`
|
||||
Amoid int32 `db:"amoid" json:"amoid"`
|
||||
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 sql.NullTime `db:"createdat" json:"createdat"`
|
||||
Subdomain string `db:"subdomain" json:"subdomain"`
|
||||
Amouserid int32 `db:"amouserid" json:"amouserid"`
|
||||
Country string `db:"country" json:"country"`
|
||||
}
|
||||
|
||||
type Utm struct {
|
||||
ID int64 `db:"id" json:"id"`
|
||||
Amofieldid int32 `db:"amofieldid" json:"amofieldid"`
|
||||
Quizid int32 `db:"quizid" json:"quizid"`
|
||||
Accountid int32 `db:"accountid" json:"accountid"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Createdat sql.NullTime `db:"createdat" json:"createdat"`
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
10
go.mod
10
go.mod
@ -10,7 +10,7 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/rs/xid v1.5.0
|
||||
google.golang.org/protobuf v1.32.0
|
||||
google.golang.org/protobuf v1.33.0
|
||||
penahub.gitlab.yandexcloud.net/backend/penahub_common v0.0.0-20240202120244-c4ef330cfe5d
|
||||
penahub.gitlab.yandexcloud.net/backend/quiz/core.git v0.0.0-20240219174804-d78fd38511af
|
||||
)
|
||||
@ -18,7 +18,7 @@ require (
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
@ -33,11 +33,13 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/sqlc-dev/pqtype v0.3.0 // indirect
|
||||
github.com/sqlc-dev/sqlc v1.26.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
golang.org/x/crypto v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.20.0 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
|
9
go.sum
9
go.sum
@ -33,6 +33,7 @@ github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -86,6 +87,10 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/sqlc-dev/pqtype v0.3.0 h1:b09TewZ3cSnO5+M1Kqq05y0+OjqIptxELaSayg7bmqk=
|
||||
github.com/sqlc-dev/pqtype v0.3.0/go.mod h1:oyUjp5981ctiL9UYvj1bVvCKi8OXkCa0u645hce7CAs=
|
||||
github.com/sqlc-dev/sqlc v1.26.0 h1:bW6TA1vVdi2lfqsEddN5tSznRMYcWez7hf+AOqSiEp8=
|
||||
github.com/sqlc-dev/sqlc v1.26.0/go.mod h1:k2F3RWilLCup3D0XufrzZENCyXjtplALmHDmOt4v5bs=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
@ -98,8 +103,11 @@ github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVS
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
||||
@ -122,6 +130,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
@ -36,6 +36,7 @@ func AnswererChain() fiber.Handler {
|
||||
|
||||
func JWTAuth() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
//todo также сделать для хуков на добавление удаление в амо
|
||||
if c.Path() == "/quiz/logo" {
|
||||
return c.Next()
|
||||
}
|
||||
|
277
model/amo.go
Normal file
277
model/amo.go
Normal file
@ -0,0 +1,277 @@
|
||||
package model
|
||||
|
||||
type User struct {
|
||||
/* - айдишник в нашей системе Primary Key*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - id пользователя из токена в нашей системе*/
|
||||
Accountid string `json:"AccountID"`
|
||||
/* - айдишник пользователя в амо*/
|
||||
AmoID int32 `json:"AmocrmID"`
|
||||
/* - имя аккаунта в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - почта пользователя из амо*/
|
||||
Email string `json:"Email"`
|
||||
/* - роль пользователя в амо*/
|
||||
Role int32 `json:"Role"`
|
||||
/* - группы пользователя в амо*/
|
||||
Group int32 `json:"Group"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания аккаунта*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
/* - поддомен организации в амо*/
|
||||
Subdomain string `json:"Subdomain"`
|
||||
/* - айдишник пользвателя, который подключал интеграцию*/
|
||||
Amouserid int32 `json:"AmoUserID"`
|
||||
/* - страна указанная в настройках амо*/
|
||||
Country string `json:"Country"`
|
||||
}
|
||||
|
||||
type UserGroups struct {
|
||||
ID int `json:"id" bson:"id"`
|
||||
Name string `json:"name" bson:"name"`
|
||||
UUID interface{} `json:"uuid" bson:"uuid"`
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
AccountID string `json:"account_id"` // id в квизе
|
||||
RefreshToken string `json:"refresh_token"` // 80 дней
|
||||
AccessToken string `json:"access_token"` // 20 минут
|
||||
AuthCode string `json:"auth_code"`
|
||||
Expiration int64 `json:"expiration"` // таймшамп времени когда кончится AccessToken
|
||||
CreatedAt int64 `json:"created_at"` // таймшамп времени создания, нужен для отслеживания 80 дней
|
||||
}
|
||||
|
||||
type Pipeline struct {
|
||||
// айдишник в нашей системе Primary Key
|
||||
ID int64 `json:"ID"`
|
||||
/* - айдишник воронки в амо*/
|
||||
Amoid int32 `json:"AmoID"`
|
||||
/* - связь с аккаунтом в интеграции амо id аккаунта в амо*/
|
||||
AccountID int32 `json:"AccountID"`
|
||||
/* - название воронки в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - флаг архивной воронки в амо*/
|
||||
Isarchive bool `json:"IsArchive"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания воронки в нашей системе*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type Step struct {
|
||||
/* - айдишник в нашей системе Primary Key*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - айдишник шага воронки в амо*/
|
||||
Amoid int32 `json:"AmoID"`
|
||||
/* - айдишник воронки в амо*/
|
||||
Pipelineid int32 `json:"PipelineID"`
|
||||
/* - связь с аккаунтом в интеграции амо id в амо*/
|
||||
Accountid int32 `json:"AccountID"`
|
||||
/* - название воронки в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - цвет шага в амо*/
|
||||
Color string `json:"Color"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания воронки в нашей системе*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type Tag struct {
|
||||
/* - айдишник в нашей системе Primary Key*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - айдишник тега в амо*/
|
||||
Amoid int32 `json:"AmoID"`
|
||||
/* - связь с аккаунтом в интеграции амо id аккаунта в амо*/
|
||||
Accountid int32 `json:"AccountID"`
|
||||
/* - сущность, к которой принадлежит этот тег. Наверное, стоит сделать через enum в базе*/
|
||||
Entity EntityType `json:"Entity"`
|
||||
/* - название тега в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - цвет тега в амо*/
|
||||
Color *string `json:"Color"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания тега в нашей системе*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type Field struct {
|
||||
/* - айдишник в нашей системе Primary Key*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - айдишник кастомного поля в амо*/
|
||||
Amoid int32 `json:"AmoID"`
|
||||
/* - кодовое слово в амо*/
|
||||
Code string `json:"Code"`
|
||||
/* - связь с аккаунтом в интеграции амо id аккаунта в амо*/
|
||||
Accountid int32 `json:"AccountID"`
|
||||
/* - название воронки в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - тип сущности в амо, для которой это кастомное поле*/
|
||||
Entity EntityType `json:"Entity"`
|
||||
/* - тип поля https://www.amocrm.ru/developers/content/crm_platform/custom-fields#%D0%94%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%BD%D1%8B%D0%B5-%D1%82%D0%B8%D0%BF%D1%8B-%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9*/
|
||||
Type FieldType `json:"Type"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания воронки в нашей системе*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type EntityType string
|
||||
|
||||
const (
|
||||
LeadsType EntityType = "leads"
|
||||
ContactsType EntityType = "contacts"
|
||||
CompaniesType EntityType = "companies"
|
||||
CustomersType EntityType = "customers"
|
||||
)
|
||||
|
||||
type Rule struct {
|
||||
/* - айдишник в нашей системе*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - связь с аккаунтом в интеграции амо id в амо*/
|
||||
Accountid int32 `json:"AccountID"`
|
||||
/* - айдишник опроса*/
|
||||
Quizid int32 `json:"QuizID"`
|
||||
/* - айдишник ответственного за сделку*/
|
||||
Performerid int32 `json:"PerformerID"`
|
||||
/* - айдишник воронки*/
|
||||
Pipelineid int32 `json:"PipelineID"`
|
||||
/* - айдишник этапа*/
|
||||
Stepid int32 `json:"StepID"`
|
||||
/* - список UTM для этого опроса*/
|
||||
Utms []int32 `json:"UTMs"`
|
||||
/* - правила заполнения полей сущностей в амо*/
|
||||
Fieldsrule Fieldsrule `json:"FieldsRule"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания воронки в нашей системе*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type Fieldsrule struct {
|
||||
Lead []FieldRule `json:"Lead"`
|
||||
Contact ContactRules `json:"Contact"`
|
||||
Company []FieldRule `json:"Company"`
|
||||
Customer []FieldRule `json:"Customer"`
|
||||
}
|
||||
|
||||
type FieldRule struct {
|
||||
/* - сопоставление айдишника вопроса полю, которое будет заполняться ответом. соответственно QuestionID это айдишник вопроса. это я так мэпу пытался записать*/
|
||||
Questionid map[int]int `json:"QuestionID"` // ключ id вопроса значение id астомного поля
|
||||
}
|
||||
|
||||
type ContactRules struct {
|
||||
// ключ имя, значение id кастомного поля
|
||||
ContactRuleMap map[string]int
|
||||
}
|
||||
|
||||
type QuizContact struct {
|
||||
FormContact struct {
|
||||
Fields struct {
|
||||
Name ContactField `json:"name"`
|
||||
Email ContactField `json:"email"`
|
||||
Phone ContactField `json:"phone"`
|
||||
Text ContactField `json:"text"`
|
||||
Address ContactField `json:"address"`
|
||||
} `json:"fields"`
|
||||
} `json:"formContact"`
|
||||
}
|
||||
|
||||
type ContactField struct {
|
||||
Text string `json:"text"`
|
||||
InnerText string `json:"innerText"`
|
||||
Key string `json:"key"`
|
||||
Required bool `json:"required"`
|
||||
Used bool `json:"used"`
|
||||
}
|
||||
|
||||
type ContactQuizConfig string
|
||||
|
||||
const (
|
||||
TypeContactName ContactQuizConfig = "name"
|
||||
TypeContactEmail ContactQuizConfig = "email"
|
||||
TypeContactPhone ContactQuizConfig = "phone"
|
||||
TypeContactText ContactQuizConfig = "text"
|
||||
TypeContactAddress ContactQuizConfig = "address"
|
||||
)
|
||||
|
||||
type UTM struct {
|
||||
/* - айдишник в нашей системе Primary Key*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - айдишник кастомного поля в амо*/
|
||||
Amofieldid int32 `json:"AmoFieldID"`
|
||||
/* - айдишник квиза*/
|
||||
Quizid int32 `json:"QuizID"`
|
||||
/* - связь с аккаунтом в интеграции амо id амо*/
|
||||
Accountid int32 `json:"AccountID"`
|
||||
/* - название тега в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - флаг мягкого удаления*/
|
||||
Deleted bool `json:"Deleted"`
|
||||
/* - таймштамп создания тега в нашей системе*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type FieldType string
|
||||
|
||||
const (
|
||||
TypeAmoText FieldType = "text" //Текст
|
||||
TypeAmoNumeric FieldType = "numeric" //Число
|
||||
TypeAmoCheckbox FieldType = "checkbox" //Флаг
|
||||
TypeAmoSelect FieldType = "select" //Список
|
||||
TypeAmoMultiselect FieldType = "multiselect" //Мультисписок
|
||||
TypeAmoDate FieldType = "date" //Дата
|
||||
TypeAmoUrl FieldType = "url" // Ссылка
|
||||
TypeAmoTextarea FieldType = "textarea" // Текстовая область
|
||||
TypeAmoRadiobutton FieldType = "radiobutton" // Переключатель
|
||||
TypeAmoStreetAddress FieldType = "streetaddress" // Короткий адрес
|
||||
TypeAmoSmartAddress FieldType = "smart_address" // Адрес
|
||||
TypeAmoBirthday FieldType = "birthday" // День рождения
|
||||
TypeAmoLegalEntity FieldType = "legal_entity" // Юр. лицо
|
||||
TypeAmoDateTime FieldType = "date_time" // Дата и время
|
||||
TypeAmoPrice FieldType = "price" //Цена
|
||||
TypeAmoCategory FieldType = "category" // Категория
|
||||
TypeAmoItems FieldType = "items" // Предметы
|
||||
TypeAmoTrackingData FieldType = "tracking_data" // Отслеживаемые данные
|
||||
TypeAmoLinkedEntity FieldType = "linked_entity" // Связь с другим элементом
|
||||
TypeAmoChainedList FieldType = "chained_list" // Каталоги и списки (платная опция Супер-поля)
|
||||
TypeAmoMonetary FieldType = "monetary" // Денежное (платная опция Супер-поля)
|
||||
TypeAmoFile FieldType = "file" // Файл
|
||||
TypeAmoPayer FieldType = "payer" // Плательщик (только в списке Счета-покупки)
|
||||
TypeAmoSupplier FieldType = "supplier" // Поставщик (только в списке Счета-покупки)
|
||||
TypeAmoMultiText FieldType = "multitext" // что то чего нет в списке полей но она есть в амо))
|
||||
)
|
||||
|
||||
var TypeMapping = map[string]FieldType{
|
||||
"variant": TypeAmoText, //TypeAmoChainedList,
|
||||
"images": TypeAmoText, //TypeAmoFile,
|
||||
"varimg": TypeAmoText, //TypeAmoFile,
|
||||
"file": TypeAmoFile,
|
||||
"text": TypeAmoText,
|
||||
"emoji": TypeAmoText,
|
||||
"select": TypeAmoText, //TypeAmoSelect,
|
||||
"date": TypeAmoText, //TypeAmoDate,
|
||||
"number": TypeAmoText, //TypeAmoNumeric,
|
||||
"page": TypeAmoText,
|
||||
"rating": TypeAmoText,
|
||||
"result": TypeAmoText,
|
||||
}
|
||||
|
||||
type AmoUsersTrueResults struct {
|
||||
QuizID int64
|
||||
AnswerID int64
|
||||
Result bool
|
||||
QuestionID int64
|
||||
Content string
|
||||
Session string
|
||||
AccessToken string
|
||||
AmoAccountID int32
|
||||
UTMs []int32
|
||||
FieldsRule Fieldsrule
|
||||
PerformerID int32
|
||||
StepID int32
|
||||
PipelineID int32
|
||||
PerformerName string
|
||||
}
|
26
model/amoReq.go
Normal file
26
model/amoReq.go
Normal file
@ -0,0 +1,26 @@
|
||||
package model
|
||||
|
||||
type ListDeleteUTMIDsReq struct {
|
||||
/* - список айдишников utm которые удалить*/
|
||||
Utms []int32 `json:"utms"`
|
||||
}
|
||||
|
||||
type PaginationReq struct {
|
||||
/* - указание страницы пагинации. Если страница не указана, применять 0*/
|
||||
Page int `json:"page"`
|
||||
/* - указание размера страницы пагинации. По умолчанию применять 25*/
|
||||
Size int32 `json:"size"`
|
||||
}
|
||||
|
||||
type RulesReq struct {
|
||||
PerformerID int32 // айдишник ответственного за сделку
|
||||
PipelineID int32 // айдишник воронки
|
||||
StepID int32 // айдишник этапа
|
||||
Utms []int32 // список UTM для этого опроса
|
||||
Fieldsrule Fieldsrule // правила заполнения полей сущностей в амо
|
||||
}
|
||||
|
||||
type SaveUserListUTMReq struct {
|
||||
/* - список utm для сохранения. сохранять только те, которых в этом аккаунте ещё нет*/
|
||||
Utms []UTM `json:"utms"`
|
||||
}
|
72
model/amoResp.go
Normal file
72
model/amoResp.go
Normal file
@ -0,0 +1,72 @@
|
||||
package model
|
||||
|
||||
type ConnectAccountResp struct {
|
||||
/* - ссылка для авторизации в амо*/
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
type GetCurrentAccountResp struct {
|
||||
/* - айдишник в нашей системе Primary Key*/
|
||||
ID int64 `json:"ID"`
|
||||
/* - имя аккаунта в амо*/
|
||||
Name string `json:"Name"`
|
||||
/* - поддомен организации в амо*/
|
||||
Subdomain string `json:"Subdomain"`
|
||||
/* - id пользователя из токена в нашей системе*/
|
||||
Accountid string `json:"AccountID"`
|
||||
/* - айдишник пользвателя, который подключал интеграцию*/
|
||||
Amouserid int32 `json:"AmoUserID"`
|
||||
/* - связь с аккаунтом в амо*/
|
||||
Amocrmid int32 `json:"AmocrmID"`
|
||||
/* - страна указанная в настройках амо*/
|
||||
Country string `json:"Country"`
|
||||
/* - таймштамп создания аккаунта*/
|
||||
Createdat int64 `json:"CreatedAt"`
|
||||
}
|
||||
|
||||
type GetListUserUTMResp struct {
|
||||
/* - общее количество юзеров, которые у нас закешированы для этого пользователя*/
|
||||
Count int64 `json:"count"`
|
||||
/* - список юзеров, которые были закешированы нашим сервисом*/
|
||||
Items []UTM `json:"items"`
|
||||
}
|
||||
|
||||
type ListSavedIDUTMResp struct {
|
||||
/* - список айдишников сохранённых меток*/
|
||||
Ids []int64 `json:"IDs"`
|
||||
}
|
||||
|
||||
type UserListFieldsResp struct {
|
||||
/* - общее количество кастомных полей, которые у нас закешированы для этого пользователя*/
|
||||
Count int64 `json:"count"`
|
||||
/* - список кастомных полей, которые были закешированы нашим сервисом*/
|
||||
Items []Field `json:"items"`
|
||||
}
|
||||
|
||||
type UserListPipelinesResp struct {
|
||||
/* - общее количество воронок, которые у нас закешированы для этого пользователя*/
|
||||
Count int64 `json:"count"`
|
||||
/* - список воронок, которые были закешированы нашим сервисом*/
|
||||
Items []Pipeline `json:"items"`
|
||||
}
|
||||
|
||||
type UserListResp struct {
|
||||
/* - общее количество юзеров, которые у нас закешированы для этого пользователя*/
|
||||
Count int64 `json:"count"`
|
||||
/* - список юзеров, которые были закешированы нашим сервисом*/
|
||||
Items []User `json:"items"`
|
||||
}
|
||||
|
||||
type UserListStepsResp struct {
|
||||
/* - список шагов воронок, которые были закешированы нашим сервисом*/
|
||||
Items []Step `json:"items"`
|
||||
/* - общее количество шагов воронок, которые у нас закешированы для этого пользователя*/
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
type UserListTagsResp struct {
|
||||
/* - общее количество тегов, которые у нас закешированы для этого пользователя*/
|
||||
Count int64 `json:"count"`
|
||||
/* - список тегов, которые были закешированы нашим сервисом*/
|
||||
Items []Tag `json:"items"`
|
||||
}
|
1074
repository/amo/amo.go
Normal file
1074
repository/amo/amo.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -83,6 +83,7 @@ func (r *AnswerRepository) GetAllAnswersByQuizID(ctx context.Context, session st
|
||||
}
|
||||
|
||||
for _, row := range rows {
|
||||
//todo тут забыл добавить проверку на то что minio !=nil
|
||||
/*if row.Questiontype == model.TypeFile {
|
||||
fmt.Println("GALL", row.Qid, row.QuestionID, row.Content)
|
||||
fileURL, err := r.answerMinio.GetAnswerURL(ctx, row.Qid.UUID.String(), row.QuestionID, row.Content.String)
|
||||
|
@ -245,12 +245,12 @@ func (r *QuestionRepository) UpdateQuestion(ctx context.Context, record model.Qu
|
||||
params = append(params, record.Required, record.Version, record.Id)
|
||||
|
||||
var placeholders []any
|
||||
for i:=1;i<=len(params);i++ {
|
||||
for i := 1; i <= len(params); i++ {
|
||||
placeholders = append(placeholders, i)
|
||||
}
|
||||
|
||||
query = fmt.Sprintf(query, placeholders...)
|
||||
|
||||
|
||||
_, err := r.pool.ExecContext(ctx, query, params...)
|
||||
return err
|
||||
}
|
||||
@ -455,3 +455,33 @@ func (r *QuestionRepository) ForSortingResults(ctx context.Context, allAnswers [
|
||||
|
||||
return sortedAllAnswers, nil
|
||||
}
|
||||
|
||||
func (r *QuestionRepository) GetQuestionListByIDs(ctx context.Context, ids []int32) ([]model.Question, error) {
|
||||
rows, err := r.queries.GetQuestionListByIDs(ctx, ids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var questions []model.Question
|
||||
for _, row := range rows {
|
||||
question := 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,
|
||||
}
|
||||
|
||||
questions = append(questions, question)
|
||||
}
|
||||
|
||||
return questions, nil
|
||||
}
|
||||
|
@ -18,6 +18,12 @@ packages:
|
||||
- "./dal/schema/000006_init.down.sql"
|
||||
- "./dal/schema/000007_init.up.sql"
|
||||
- "./dal/schema/000007_init.down.sql"
|
||||
- "./dal/schema/000008_init.up.sql"
|
||||
- "./dal/schema/000008_init.down.sql"
|
||||
- "./dal/schema/000009_init.up.sql"
|
||||
- "./dal/schema/000009_init.down.sql"
|
||||
- "./dal/schema/000010_init.up.sql"
|
||||
- "./dal/schema/000010_init.down.sql"
|
||||
engine: "postgresql"
|
||||
emit_json_tags: true
|
||||
emit_db_tags: true
|
||||
|
Loading…
Reference in New Issue
Block a user