670 lines
20 KiB
Go
670 lines
20 KiB
Go
package quiz
|
||
|
||
import (
|
||
"fmt"
|
||
"gitea.pena/PenaSide/common/log_mw"
|
||
"gitea.pena/SQuiz/common/dal"
|
||
"gitea.pena/SQuiz/common/middleware"
|
||
"gitea.pena/SQuiz/common/model"
|
||
"gitea.pena/SQuiz/common/repository/quiz"
|
||
"gitea.pena/SQuiz/core/internal/brokers"
|
||
"gitea.pena/SQuiz/core/internal/models"
|
||
"github.com/gofiber/fiber/v2"
|
||
"strconv"
|
||
"time"
|
||
"unicode/utf8"
|
||
)
|
||
|
||
type Deps struct {
|
||
DAL *dal.DAL
|
||
ProducerGigaChat *brokers.Producer
|
||
}
|
||
|
||
type Quiz struct {
|
||
dal *dal.DAL
|
||
producerGigaChat *brokers.Producer
|
||
}
|
||
|
||
func NewQuizController(deps Deps) *Quiz {
|
||
return &Quiz{
|
||
dal: deps.DAL,
|
||
producerGigaChat: deps.ProducerGigaChat,
|
||
}
|
||
}
|
||
|
||
type CreateQuizReq struct {
|
||
Fingerprinting bool `json:"fingerprinting"` // true if you need to store device id
|
||
Repeatable bool `json:"repeatable"` // make it true for allow more than one quiz checkouting
|
||
NotePrevented bool `json:"note_prevented"` // note answers even if the quiz was aborted
|
||
MailNotifications bool `json:"mail_notifications"` // set true if you want get an email with every quiz passing
|
||
UniqueAnswers bool `json:"unique_answers"` // set true if we you mention only last quiz passing
|
||
|
||
Name string `json:"name"` // max 700 chars
|
||
Description string `json:"description"`
|
||
Config string `json:"config"` // serialize json with config for page rules. fill it up only if implement one form scenario
|
||
Status string `json:"status"` // status of quiz as enum. see Status const. fill it up only if implement one form scenario
|
||
Limit uint64 `json:"limit"` // max count of quiz passing
|
||
DueTo uint64 `json:"due_to"` // time when quiz is end
|
||
|
||
QuestionCnt uint64 `json:"question_cnt"` // for creating at one request
|
||
|
||
TimeOfPassing uint64 `json:"time_of_passing"` // amount of seconds for give all appropriate answers for quiz
|
||
Pausable bool `json:"pausable"` // true allows to pause the quiz taking
|
||
|
||
Super bool `json:"super"` // set true if you want to create group
|
||
GroupId uint64 `json:"group_id"` // if you create quiz in group provide there the id of super quiz
|
||
}
|
||
|
||
// CreateQuiz handler for quiz creating request
|
||
func (r *Quiz) CreateQuiz(ctx *fiber.Ctx) error {
|
||
var req CreateQuizReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
hlogger := log_mw.ExtractLogger(ctx)
|
||
|
||
// check that we can store name
|
||
if utf8.RuneCountInString(req.Name) > 700 {
|
||
return ctx.Status(fiber.StatusUnprocessableEntity).SendString("name field should have less then 700 chars")
|
||
}
|
||
|
||
// status should be empty or equal one of status enum strings
|
||
// I mean not draft, template, stop, start statuses
|
||
if req.Status != "" &&
|
||
req.Status != model.StatusDraft &&
|
||
req.Status != model.StatusTemplate &&
|
||
req.Status != model.StatusAI &&
|
||
req.Status != model.StatusStop &&
|
||
req.Status != model.StatusStart {
|
||
return ctx.Status(fiber.StatusNotAcceptable).SendString("status on creating must be only draft,template,stop,start")
|
||
}
|
||
|
||
// DueTo should be bigger then now
|
||
if req.DueTo != 0 && req.DueTo <= uint64(time.Now().Unix()) {
|
||
return ctx.Status(fiber.StatusNotAcceptable).SendString("due to time must be lesser then now")
|
||
}
|
||
|
||
// you can pause quiz only if it has deadline for passing
|
||
if req.Pausable && req.TimeOfPassing == 0 {
|
||
return ctx.Status(fiber.StatusConflict).SendString("you can pause quiz only if it has deadline for passing")
|
||
}
|
||
|
||
record := model.Quiz{
|
||
AccountId: accountId,
|
||
Fingerprinting: req.Fingerprinting,
|
||
Repeatable: req.Repeatable,
|
||
NotePrevented: req.NotePrevented,
|
||
MailNotifications: req.MailNotifications,
|
||
UniqueAnswers: req.UniqueAnswers,
|
||
Name: req.Name,
|
||
Description: req.Description,
|
||
Config: req.Config,
|
||
Status: req.Status,
|
||
Limit: req.Limit,
|
||
DueTo: req.DueTo,
|
||
TimeOfPassing: req.TimeOfPassing,
|
||
Pausable: req.Pausable,
|
||
QuestionsCount: req.QuestionCnt,
|
||
ParentIds: []int32{},
|
||
Super: req.Super,
|
||
GroupId: req.GroupId,
|
||
}
|
||
|
||
quizID, err := r.dal.QuizRepo.CreateQuiz(ctx.Context(), &record)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
hlogger.Emit(models.InfoQuizCreated{
|
||
CtxUserID: accountId,
|
||
CtxIDInt: int64(quizID),
|
||
})
|
||
|
||
return ctx.Status(fiber.StatusCreated).JSON(record)
|
||
}
|
||
|
||
// GetQuizListReq request struct for paginated quiz table
|
||
type GetQuizListReq struct {
|
||
Limit uint64 `json:"limit"`
|
||
Page uint64 `json:"page"`
|
||
From int64 `json:"from"`
|
||
To int64 `json:"to"`
|
||
|
||
Search string `json:"search"`
|
||
Status string `json:"status"`
|
||
Deleted bool `json:"deleted"`
|
||
Archived bool `json:"archived"`
|
||
Super bool `json:"super"`
|
||
GroupId uint64 `json:"group_id"`
|
||
}
|
||
|
||
type GetQuizListResp struct {
|
||
Count uint64 `json:"count"`
|
||
Items []model.Quiz `json:"items"`
|
||
}
|
||
|
||
// GetQuizList handler for paginated list quiz
|
||
func (r *Quiz) GetQuizList(ctx *fiber.Ctx) error {
|
||
var req GetQuizListReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
if req.Status != "" &&
|
||
req.Status != model.StatusStop &&
|
||
req.Status != model.StatusStart &&
|
||
req.Status != model.StatusDraft &&
|
||
req.Status != model.StatusTemplate &&
|
||
req.Status != model.StatusAI &&
|
||
req.Status != model.StatusTimeout &&
|
||
req.Status != model.StatusOffLimit {
|
||
return ctx.Status(fiber.StatusNotAcceptable).SendString("inappropriate status, allowed only '', " +
|
||
"'stop','start','draft', 'template','timeout','offlimit'")
|
||
}
|
||
|
||
res, cnt, err := r.dal.QuizRepo.GetQuizList(ctx.Context(),
|
||
quiz.GetQuizListDeps{
|
||
Limit: req.Limit,
|
||
Offset: req.Limit * req.Page,
|
||
From: uint64(req.From),
|
||
To: uint64(req.To),
|
||
Group: req.GroupId,
|
||
Deleted: req.Deleted,
|
||
Archived: req.Archived,
|
||
Super: req.Super,
|
||
Search: req.Search,
|
||
Status: req.Status,
|
||
AccountId: accountId,
|
||
})
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.JSON(GetQuizListResp{
|
||
Items: res,
|
||
Count: cnt,
|
||
})
|
||
}
|
||
|
||
type UpdateQuizReq struct {
|
||
Id uint64 `json:"id"`
|
||
Fingerprinting bool `json:"fp"`
|
||
Repeatable bool `json:"rep"`
|
||
NotePrevented bool `json:"note_prevented"`
|
||
MailNotifications bool `json:"mailing"`
|
||
UniqueAnswers bool `json:"uniq"`
|
||
Name string `json:"name"`
|
||
Description string `json:"desc"`
|
||
Config string `json:"conf"`
|
||
Status string `json:"status"`
|
||
Limit uint64 `json:"limit"`
|
||
DueTo uint64 `json:"due_to"`
|
||
TimeOfPassing uint64 `json:"time_of_passing"`
|
||
Pausable bool `json:"pausable"`
|
||
QuestionCnt uint64 `json:"question_cnt"` // for creating at one request
|
||
Super bool `json:"super"`
|
||
GroupId uint64 `json:"group_id"`
|
||
}
|
||
|
||
type UpdateResp struct {
|
||
Updated uint64 `json:"updated"`
|
||
}
|
||
|
||
func (r *Quiz) UpdateQuiz(ctx *fiber.Ctx) error {
|
||
var req UpdateQuizReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
hlogger := log_mw.ExtractLogger(ctx)
|
||
|
||
if req.Id == 0 {
|
||
return ctx.Status(fiber.StatusFailedDependency).SendString("need id of question for update")
|
||
}
|
||
|
||
if utf8.RuneCountInString(req.Name) > 700 {
|
||
return ctx.Status(fiber.StatusUnprocessableEntity).SendString("name field should have less then 700 chars")
|
||
}
|
||
|
||
// status should be empty or equal one of status enum strings
|
||
// I mean not draft, template, stop, start statuses
|
||
if req.Status != "" &&
|
||
req.Status != model.StatusDraft &&
|
||
req.Status != model.StatusTemplate &&
|
||
req.Status != model.StatusAI &&
|
||
req.Status != model.StatusStop &&
|
||
req.Status != model.StatusStart {
|
||
return ctx.Status(fiber.StatusNotAcceptable).SendString("status on creating must be only draft,template,stop,start")
|
||
}
|
||
|
||
// DueTo should be bigger then now
|
||
if req.DueTo != 0 && req.DueTo <= uint64(time.Now().Unix()) {
|
||
return ctx.Status(fiber.StatusNotAcceptable).SendString("due to time must be lesser then now")
|
||
}
|
||
|
||
// you can pause quiz only if it has deadline for passing
|
||
if req.Pausable && req.TimeOfPassing == 0 {
|
||
return ctx.Status(fiber.StatusConflict).SendString("you can pause quiz only if it has deadline for passing")
|
||
}
|
||
|
||
quiz, err := r.dal.QuizRepo.MoveToHistoryQuiz(ctx.Context(), req.Id, accountId)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
quiz.ParentIds = append(quiz.ParentIds, int32(quiz.Id))
|
||
quiz.Id = req.Id
|
||
quiz.Version += 1
|
||
|
||
if req.Fingerprinting != quiz.Fingerprinting {
|
||
quiz.Fingerprinting = req.Fingerprinting
|
||
}
|
||
|
||
if req.Repeatable != quiz.Repeatable {
|
||
quiz.Repeatable = req.Repeatable
|
||
}
|
||
|
||
if req.MailNotifications != quiz.MailNotifications {
|
||
quiz.MailNotifications = req.MailNotifications
|
||
}
|
||
|
||
if req.NotePrevented != quiz.NotePrevented {
|
||
quiz.NotePrevented = req.NotePrevented
|
||
}
|
||
|
||
if req.UniqueAnswers != quiz.UniqueAnswers {
|
||
quiz.UniqueAnswers = req.UniqueAnswers
|
||
}
|
||
|
||
if req.Pausable != quiz.Pausable {
|
||
quiz.Pausable = req.Pausable
|
||
}
|
||
|
||
if req.Name != "" && req.Name != quiz.Name {
|
||
quiz.Name = req.Name
|
||
}
|
||
|
||
if req.Description != "" && req.Description != quiz.Description {
|
||
quiz.Description = req.Description
|
||
}
|
||
|
||
if req.Status != "" && req.Status != quiz.Status {
|
||
quiz.Status = req.Status
|
||
}
|
||
|
||
if req.TimeOfPassing != quiz.TimeOfPassing {
|
||
quiz.TimeOfPassing = req.TimeOfPassing
|
||
}
|
||
|
||
if req.DueTo != quiz.DueTo {
|
||
quiz.DueTo = req.DueTo
|
||
}
|
||
|
||
if req.Limit != quiz.Limit {
|
||
quiz.Limit = req.Limit
|
||
}
|
||
|
||
if req.Config != "" && req.Config != quiz.Config {
|
||
quiz.Config = req.Config
|
||
}
|
||
|
||
if req.Super != quiz.Super {
|
||
quiz.Super = req.Super
|
||
}
|
||
|
||
if req.GroupId != quiz.GroupId {
|
||
quiz.GroupId = req.GroupId
|
||
}
|
||
|
||
quiz.QuestionsCount = req.QuestionCnt
|
||
|
||
quiz.ParentIds = append(quiz.ParentIds, int32(quiz.Id))
|
||
|
||
if err := r.dal.QuizRepo.UpdateQuiz(ctx.Context(), accountId, quiz); err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
if req.Status == model.StatusStart {
|
||
hlogger.Emit(models.InfoQuizPublish{
|
||
CtxUserID: accountId,
|
||
CtxIDInt: int64(quiz.Id),
|
||
})
|
||
}
|
||
if req.Status == model.StatusStop {
|
||
hlogger.Emit(models.InfoQuizStop{
|
||
CtxUserID: accountId,
|
||
CtxIDInt: int64(quiz.Id),
|
||
})
|
||
}
|
||
|
||
return ctx.JSON(UpdateResp{
|
||
Updated: quiz.Id,
|
||
})
|
||
}
|
||
|
||
// CopyQuizReq request struct for copy quiz
|
||
type CopyQuizReq struct {
|
||
Id uint64 `json:"id"`
|
||
}
|
||
|
||
// CopyQuiz request handler for copy quiz
|
||
func (r *Quiz) CopyQuiz(ctx *fiber.Ctx) error {
|
||
var req CopyQuizReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
if req.Id == 0 {
|
||
return ctx.Status(fiber.StatusFailedDependency).SendString("no id provided")
|
||
}
|
||
|
||
quiz, err := r.dal.QuizRepo.CopyQuiz(ctx.Context(), accountId, req.Id)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.JSON(UpdateResp{
|
||
Updated: quiz.Id,
|
||
})
|
||
}
|
||
|
||
// GetQuizHistoryReq struct of get history request
|
||
type GetQuizHistoryReq struct {
|
||
Id uint64 `json:"id"`
|
||
Limit uint64 `json:"l"`
|
||
Page uint64 `json:"p"`
|
||
}
|
||
|
||
// GetQuizHistory handler for history of quiz
|
||
func (r *Quiz) GetQuizHistory(ctx *fiber.Ctx) error {
|
||
var req GetQuizHistoryReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
if req.Id == 0 {
|
||
return ctx.Status(fiber.StatusFailedDependency).SendString("no id provided")
|
||
}
|
||
|
||
history, err := r.dal.QuizRepo.QuizHistory(ctx.Context(), quiz.QuizHistoryDeps{
|
||
Id: req.Id,
|
||
Limit: req.Limit,
|
||
Offset: req.Page * req.Limit,
|
||
AccountId: accountId,
|
||
})
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.Status(fiber.StatusCreated).JSON(history)
|
||
}
|
||
|
||
// DeactivateReq request structure for archiving and deleting
|
||
type DeactivateReq struct {
|
||
Id uint64 `json:"id"`
|
||
}
|
||
|
||
type DeactivateResp struct {
|
||
Deactivated uint64 `json:"deactivated"`
|
||
}
|
||
|
||
// DeleteQuiz handler for fake delete quiz
|
||
func (r *Quiz) DeleteQuiz(ctx *fiber.Ctx) error {
|
||
var req DeactivateReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
hlogger := log_mw.ExtractLogger(ctx)
|
||
|
||
if req.Id == 0 {
|
||
return ctx.Status(fiber.StatusFailedDependency).SendString("id for deleting is required")
|
||
}
|
||
|
||
deleted, err := r.dal.QuizRepo.DeleteQuiz(ctx.Context(), accountId, req.Id)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
hlogger.Emit(models.InfoQuizDelete{
|
||
CtxUserID: accountId,
|
||
CtxIDInt: int64(req.Id),
|
||
})
|
||
|
||
return ctx.JSON(DeactivateResp{
|
||
Deactivated: deleted.Id,
|
||
})
|
||
}
|
||
|
||
// ArchiveQuiz handler for archiving quiz
|
||
func (r *Quiz) ArchiveQuiz(ctx *fiber.Ctx) error {
|
||
var req DeactivateReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
accountId, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
if req.Id == 0 {
|
||
return ctx.Status(fiber.StatusFailedDependency).SendString("id for archive quiz is required")
|
||
}
|
||
|
||
archived, err := r.dal.QuizRepo.DeleteQuiz(ctx.Context(), accountId, req.Id)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.JSON(DeactivateResp{
|
||
Deactivated: archived.Id,
|
||
})
|
||
}
|
||
|
||
type QuizMoveReq struct {
|
||
Qid, AccountID string
|
||
}
|
||
|
||
func (r *Quiz) QuizMove(ctx *fiber.Ctx) error {
|
||
var req QuizMoveReq
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
if req.Qid == "" || req.AccountID == "" {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request qid and accountID is required")
|
||
}
|
||
|
||
resp, err := r.dal.QuizRepo.QuizMove(ctx.Context(), req.Qid, req.AccountID)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.Status(fiber.StatusOK).JSON(resp)
|
||
}
|
||
|
||
func (r *Quiz) TemplateCopy(ctx *fiber.Ctx) error {
|
||
accountID, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
hlogger := log_mw.ExtractLogger(ctx)
|
||
|
||
var req struct {
|
||
Qid string `json:"qid"`
|
||
}
|
||
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
if req.Qid == "" {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request qid is required")
|
||
}
|
||
|
||
qizID, err := r.dal.QuizRepo.TemplateCopy(ctx.Context(), accountID, req.Qid)
|
||
if err != nil {
|
||
fmt.Println("TEMPLERR", err)
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
hlogger.Emit(models.InfoQuizTemplateCopy{
|
||
CtxUserID: accountID,
|
||
// todo либо возвращать id копируемого квиза либо поле с qid
|
||
// для него потому что id получаем уже в запросе sql
|
||
//CtxID: req.Qid,
|
||
CtxQuizID: qizID,
|
||
})
|
||
|
||
return ctx.Status(fiber.StatusOK).JSON(fiber.Map{"id": qizID})
|
||
}
|
||
|
||
func (r *Quiz) CreateQuizAuditory(ctx *fiber.Ctx) error {
|
||
accountID, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
account, err := r.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString("can`t get account by account id")
|
||
}
|
||
|
||
if _, ok := account.Privileges["quizGigaChat"]; !ok {
|
||
return ctx.Status(fiber.StatusPaymentRequired).SendString("payment required")
|
||
}
|
||
|
||
var req struct {
|
||
Sex int32 `json:"sex"` // 0 - female, 1 - male, 2 - not sex
|
||
Age string `json:"age"`
|
||
}
|
||
|
||
if err := ctx.BodyParser(&req); err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
|
||
}
|
||
|
||
quizIDStr := ctx.Params("quizID")
|
||
quizID, err := strconv.ParseInt(quizIDStr, 10, 64)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
|
||
}
|
||
|
||
if quizID == 0 || req.Age == "" {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request missing required fields")
|
||
}
|
||
|
||
result, err := r.dal.QuizRepo.CreateQuizAudience(ctx.Context(), quiz.DepsCreateQuizAudience{
|
||
QuizID: quizID,
|
||
Age: req.Age,
|
||
Sex: req.Sex,
|
||
})
|
||
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
err = r.producerGigaChat.ToGigaChatNotify(ctx.Context(), brokers.MessageGigaChat{
|
||
ID: result,
|
||
QuizID: quizID,
|
||
Age: req.Age,
|
||
Sex: req.Sex,
|
||
})
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.Status(fiber.StatusOK).JSON(fiber.Map{"ID": result})
|
||
}
|
||
|
||
func (r *Quiz) GetQuizAuditory(ctx *fiber.Ctx) error {
|
||
quizIDStr := ctx.Params("quizID")
|
||
quizID, err := strconv.ParseInt(quizIDStr, 10, 64)
|
||
if err != nil || quizID == 0 {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
|
||
}
|
||
|
||
accountID, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
isOwner, err := r.dal.QuizRepo.CheckQuizOwner(ctx.Context(), accountID, uint64(quizID))
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to check ownership: " + err.Error())
|
||
}
|
||
|
||
if !isOwner {
|
||
return ctx.Status(fiber.StatusForbidden).SendString("you are not the owner")
|
||
}
|
||
|
||
result, err := r.dal.QuizRepo.GetQuizAudience(ctx.Context(), quizID)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.Status(fiber.StatusOK).JSON(result)
|
||
}
|
||
|
||
func (r *Quiz) DeleteQuizAuditory(ctx *fiber.Ctx) error {
|
||
quizIDStr := ctx.Params("quizID")
|
||
quizID, err := strconv.ParseInt(quizIDStr, 10, 64)
|
||
if err != nil || quizID == 0 {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
|
||
}
|
||
|
||
audienceIDStr := ctx.Params("auditoryID")
|
||
audienceID, err := strconv.ParseInt(audienceIDStr, 10, 64)
|
||
if err != nil || audienceID == 0 {
|
||
return ctx.Status(fiber.StatusBadRequest).SendString("invalid audience ID")
|
||
}
|
||
|
||
accountID, ok := middleware.GetAccountId(ctx)
|
||
if !ok {
|
||
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
|
||
}
|
||
|
||
isOwner, err := r.dal.QuizRepo.CheckIsOwnerAudience(ctx.Context(), quizID, audienceID, accountID)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to check ownership: " + err.Error())
|
||
}
|
||
if !isOwner {
|
||
return ctx.Status(fiber.StatusForbidden).SendString("you are not the owner of this quiz audience")
|
||
}
|
||
|
||
err = r.dal.QuizRepo.DeleteQuizAudience(ctx.Context(), quizID, audienceID)
|
||
if err != nil {
|
||
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
|
||
}
|
||
|
||
return ctx.SendStatus(fiber.StatusOK)
|
||
}
|