Some checks failed
Server Check Build (NixCN CMS) TeamCity build failed
Signed-off-by: Asai Neko <sugar@sne.moe>
205 lines
5.3 KiB
Go
205 lines
5.3 KiB
Go
package service_event
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"nixcn-cms/data"
|
|
"nixcn-cms/internal/exception"
|
|
"nixcn-cms/service/shared"
|
|
"nixcn-cms/tracer"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type EventStatsData struct {
|
|
EventId string `json:"event_id" validate:"required"`
|
|
}
|
|
|
|
type EventStatsPayload struct {
|
|
Context context.Context
|
|
UserId uuid.UUID
|
|
Data *EventStatsData
|
|
}
|
|
|
|
type EventStatsResponse struct {
|
|
JoinCount int64 `json:"join_count"`
|
|
CheckinCount int64 `json:"checkin_count"`
|
|
KycPassRate float64 `json:"kyc_pass_rate"`
|
|
AgendaSubmissionCount int64 `json:"agenda_submission_count"`
|
|
}
|
|
|
|
type EventStatsResult struct {
|
|
Common shared.CommonResult
|
|
Data *EventStatsResponse
|
|
}
|
|
|
|
func (self *EventServiceImpl) Stats(payload *EventStatsPayload) (result *EventStatsResult) {
|
|
ctx, span := tracer.StartSpan(
|
|
payload.Context,
|
|
"service_event",
|
|
"stats",
|
|
)
|
|
defer span.End()
|
|
|
|
ctx = exception.ContextWithService(ctx, exception.ServiceEventStats)
|
|
|
|
eventId, err := uuid.Parse(payload.Data.EventId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusUser),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorUuidParseFailed),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 400, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
eventData, err := new(data.Event).GetEventById(ctx, eventId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusServer),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorDatabase),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 500, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
if eventData == nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusUser),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorInvalidInput),
|
|
exception.WithError(errors.New("event not found")),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 404, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
if eventData.Owner != payload.UserId {
|
|
callerData, err := new(data.User).GetByUserId(ctx, &payload.UserId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusServer),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorDatabase),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 500, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
if callerData == nil || callerData.PermissionLevel < 40 {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusUser),
|
|
exception.WithType(exception.TypeSpecific),
|
|
exception.WithOriginal(exception.EventStatsNotOwner),
|
|
exception.WithError(errors.New("only the event owner may view event stats")),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 403, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
attRepo := new(data.Attendance)
|
|
|
|
joinCount, err := attRepo.CountUsersByEventID(ctx, eventId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusServer),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorDatabase),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 500, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
checkinCount, err := attRepo.CountCheckedInUsersByEventID(ctx, eventId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusServer),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorDatabase),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 500, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
withKycCount, err := attRepo.CountWithKycByEventID(ctx, eventId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusServer),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorDatabase),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 500, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
agendaCount, err := new(data.Agenda).CountByEventId(ctx, eventId)
|
|
if err != nil {
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusServer),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonErrorDatabase),
|
|
exception.WithError(err),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 500, Exception: exc},
|
|
}
|
|
return
|
|
}
|
|
|
|
var kycPassRate float64
|
|
if joinCount > 0 {
|
|
kycPassRate = float64(withKycCount) / float64(joinCount) * 100
|
|
}
|
|
|
|
exc := exception.New(
|
|
exception.WithStatus(exception.StatusSuccess),
|
|
exception.WithType(exception.TypeCommon),
|
|
exception.WithOriginal(exception.CommonSuccess),
|
|
).Throw(ctx)
|
|
|
|
result = &EventStatsResult{
|
|
Common: shared.CommonResult{HttpCode: 200, Exception: exc},
|
|
Data: &EventStatsResponse{
|
|
JoinCount: joinCount,
|
|
CheckinCount: checkinCount,
|
|
KycPassRate: kycPassRate,
|
|
AgendaSubmissionCount: agendaCount,
|
|
},
|
|
}
|
|
return
|
|
}
|