add router for get last moderation message

This commit is contained in:
harold 2025-03-10 11:02:47 +05:00
parent 8e91a17177
commit 5bebbd7521
11 changed files with 457 additions and 1 deletions

View File

@ -491,3 +491,38 @@ func GetDonationsStats(donatService model.DonatService) echo.HandlerFunc {
return request.JSON(http.StatusOK, stats) return request.JSON(http.StatusOK, stats)
} }
} }
// DonateModeration godoc
// @Summary Get the latest donation in moderation
// @Description Get the latest donation with status 'moderation' sorted by updated_at
// @Tags Donate
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} model.DonationModeration "Latest donation in moderation"
// @Failure 400 {object} echo.HTTPError "Bad request"
// @Failure 401 {object} echo.HTTPError "Unauthorized or expired token"
// @Failure 404 {object} echo.HTTPError "No donations in moderation found"
// @Failure 500 {object} echo.HTTPError "Internal server error"
// @Router /donat/latest-moderation [get]
func DonateModeration(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error {
authData, err := donatService.CheckToken(request)
if err != nil {
slog.Error("Unauthorized")
return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
}
ctx := context.Background()
donation, err := donatService.GetDonatModeration(ctx, authData.AccountID)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}
if donation.ID == 0 { // Если донат не найден
return request.JSON(http.StatusOK, map[string]interface{}{})
}
return request.JSON(http.StatusOK, donation)
}
}

View File

@ -90,6 +90,8 @@ func IncludeDonatHandlers(
server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService)) server.POST(PREFIX+"/donat/paid", MarkDonatPaid(donatService))
server.GET(PREFIX+"/donat/period-stat", GetDonationsStats(donatService)) server.GET(PREFIX+"/donat/period-stat", GetDonationsStats(donatService))
server.GET(PREFIX+"/donat/latest-moderation", DonateModeration(donatService))
} }
func IncludeWidgetHandlers( func IncludeWidgetHandlers(

View File

@ -93,6 +93,58 @@ const docTemplate = `{
} }
} }
}, },
"/donat/latest-moderation": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the latest donation with status 'moderation' sorted by updated_at",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get the latest donation in moderation",
"responses": {
"200": {
"description": "Latest donation in moderation",
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.DonationModeration"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"404": {
"description": "No donations in moderation found",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat/period-stat": { "/donat/period-stat": {
"get": { "get": {
"security": [ "security": [
@ -1047,6 +1099,71 @@ const docTemplate = `{
} }
} }
}, },
"donat-widget_internal_model.DonationModeration": {
"type": "object",
"properties": {
"accepted": {
"description": "Донат принят на модерации",
"type": "boolean",
"example": false
},
"amount": {
"description": "Сумма доната",
"type": "integer",
"example": 2000
},
"created_at": {
"description": "Дата создания",
"type": "string",
"example": "2025-03-09T12:49:21.75005Z"
},
"donat_user": {
"description": "Имя пользователя, сделавшего донат",
"type": "string",
"example": "Петр"
},
"id": {
"description": "Уникальный идентификатор доната",
"type": "integer",
"example": 123
},
"play_content": {
"description": "Проигрывать контент",
"type": "boolean",
"example": true
},
"show_name": {
"description": "Показывать имя пользователя",
"type": "boolean",
"example": true
},
"show_text": {
"description": "Показывать текст доната",
"type": "boolean",
"example": true
},
"status": {
"description": "Статус доната (moderation, pending, viewed и т.д.)",
"type": "string",
"example": "moderation"
},
"target_id": {
"description": "ID цели (если есть)",
"type": "integer",
"example": 0
},
"text": {
"description": "Текст доната",
"type": "string",
"example": "Пиздатый стрим"
},
"updated_at": {
"description": "Дата последнего обновления",
"type": "string",
"example": "2025-03-09T12:49:21.75005Z"
}
}
},
"donat-widget_internal_model.DonationStatResponse": { "donat-widget_internal_model.DonationStatResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -86,6 +86,58 @@
} }
} }
}, },
"/donat/latest-moderation": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "Get the latest donation with status 'moderation' sorted by updated_at",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"Donate"
],
"summary": "Get the latest donation in moderation",
"responses": {
"200": {
"description": "Latest donation in moderation",
"schema": {
"$ref": "#/definitions/donat-widget_internal_model.DonationModeration"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"401": {
"description": "Unauthorized or expired token",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"404": {
"description": "No donations in moderation found",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/echo.HTTPError"
}
}
}
}
},
"/donat/period-stat": { "/donat/period-stat": {
"get": { "get": {
"security": [ "security": [
@ -1040,6 +1092,71 @@
} }
} }
}, },
"donat-widget_internal_model.DonationModeration": {
"type": "object",
"properties": {
"accepted": {
"description": "Донат принят на модерации",
"type": "boolean",
"example": false
},
"amount": {
"description": "Сумма доната",
"type": "integer",
"example": 2000
},
"created_at": {
"description": "Дата создания",
"type": "string",
"example": "2025-03-09T12:49:21.75005Z"
},
"donat_user": {
"description": "Имя пользователя, сделавшего донат",
"type": "string",
"example": "Петр"
},
"id": {
"description": "Уникальный идентификатор доната",
"type": "integer",
"example": 123
},
"play_content": {
"description": "Проигрывать контент",
"type": "boolean",
"example": true
},
"show_name": {
"description": "Показывать имя пользователя",
"type": "boolean",
"example": true
},
"show_text": {
"description": "Показывать текст доната",
"type": "boolean",
"example": true
},
"status": {
"description": "Статус доната (moderation, pending, viewed и т.д.)",
"type": "string",
"example": "moderation"
},
"target_id": {
"description": "ID цели (если есть)",
"type": "integer",
"example": 0
},
"text": {
"description": "Текст доната",
"type": "string",
"example": "Пиздатый стрим"
},
"updated_at": {
"description": "Дата последнего обновления",
"type": "string",
"example": "2025-03-09T12:49:21.75005Z"
}
}
},
"donat-widget_internal_model.DonationStatResponse": { "donat-widget_internal_model.DonationStatResponse": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@ -69,6 +69,57 @@ definitions:
streamer_id: streamer_id:
type: integer type: integer
type: object type: object
donat-widget_internal_model.DonationModeration:
properties:
accepted:
description: Донат принят на модерации
example: false
type: boolean
amount:
description: Сумма доната
example: 2000
type: integer
created_at:
description: Дата создания
example: "2025-03-09T12:49:21.75005Z"
type: string
donat_user:
description: Имя пользователя, сделавшего донат
example: Петр
type: string
id:
description: Уникальный идентификатор доната
example: 123
type: integer
play_content:
description: Проигрывать контент
example: true
type: boolean
show_name:
description: Показывать имя пользователя
example: true
type: boolean
show_text:
description: Показывать текст доната
example: true
type: boolean
status:
description: Статус доната (moderation, pending, viewed и т.д.)
example: moderation
type: string
target_id:
description: ID цели (если есть)
example: 0
type: integer
text:
description: Текст доната
example: Пиздатый стрим
type: string
updated_at:
description: Дата последнего обновления
example: "2025-03-09T12:49:21.75005Z"
type: string
type: object
donat-widget_internal_model.DonationStatResponse: donat-widget_internal_model.DonationStatResponse:
properties: properties:
amount_collected: amount_collected:
@ -454,6 +505,39 @@ paths:
summary: Create donat summary: Create donat
tags: tags:
- Donate - Donate
/donat/latest-moderation:
get:
consumes:
- application/json
description: Get the latest donation with status 'moderation' sorted by updated_at
produces:
- application/json
responses:
"200":
description: Latest donation in moderation
schema:
$ref: '#/definitions/donat-widget_internal_model.DonationModeration'
"400":
description: Bad request
schema:
$ref: '#/definitions/echo.HTTPError'
"401":
description: Unauthorized or expired token
schema:
$ref: '#/definitions/echo.HTTPError'
"404":
description: No donations in moderation found
schema:
$ref: '#/definitions/echo.HTTPError'
"500":
description: Internal server error
schema:
$ref: '#/definitions/echo.HTTPError'
security:
- BearerAuth: []
summary: Get the latest donation in moderation
tags:
- Donate
/donat/period-stat: /donat/period-stat:
get: get:
consumes: consumes:

View File

@ -102,6 +102,8 @@ type DonatService interface {
UpdateModerationSettings(ctx context.Context, streamerID int, updateModel UpdateModeration) error UpdateModerationSettings(ctx context.Context, streamerID int, updateModel UpdateModeration) error
GetDonationsStats(ctx context.Context, streamerID int, period string) (DonationSummaryResponse, error) GetDonationsStats(ctx context.Context, streamerID int, period string) (DonationSummaryResponse, error)
GetDonatModeration(ctx context.Context, streamerID int) (DonationModeration, error)
} }
type DonatRepo interface { type DonatRepo interface {
@ -154,6 +156,8 @@ type DonatRepo interface {
GetDonationsStats(ctx context.Context, streamerID int, period string) ([]DonationStat, error) GetDonationsStats(ctx context.Context, streamerID int, period string) ([]DonationStat, error)
GetDonationsSummary(ctx context.Context, streamerID int, period string) (DonationSummary, error) GetDonationsSummary(ctx context.Context, streamerID int, period string) (DonationSummary, error)
GetDonatModeration(ctx context.Context, streamerID int) (DonationModeration, error)
} }
type TargetService interface { type TargetService interface {

View File

@ -278,6 +278,21 @@ type DonationSummaryResponse struct {
Donations []DonationStatResponse `json:"donations"` Donations []DonationStatResponse `json:"donations"`
} }
type DonationModeration struct {
ID int `db:"id" json:"id" example:"123"` // Уникальный идентификатор доната
TargetID int `db:"target_id" json:"target_id" example:"0"` // ID цели (если есть)
Status string `db:"status" json:"status" example:"moderation"` // Статус доната (moderation, pending, viewed и т.д.)
Text string `db:"text" json:"text" example:"Пиздатый стрим"` // Текст доната
Amount int `db:"amount" json:"amount" example:"2000"` // Сумма доната
DonatUser string `db:"donat_user" json:"donat_user" example:"Петр"` // Имя пользователя, сделавшего донат
Accepted bool `db:"accepted" json:"accepted" example:"false"` // Донат принят на модерации
ShowName bool `db:"show_name" json:"show_name" example:"true"` // Показывать имя пользователя
ShowText bool `db:"show_text" json:"show_text" example:"true"` // Показывать текст доната
PlayContent bool `db:"play_content" json:"play_content" example:"true"` // Проигрывать контент
CreatedAt time.Time `db:"created_at" json:"created_at" example:"2025-03-09T12:49:21.75005Z"` // Дата создания
UpdatedAt time.Time `db:"updated_at" json:"updated_at" example:"2025-03-09T12:49:21.75005Z"` // Дата последнего обновления
}
//func (widget *GetWidgetDb) GetMediaUrl(mediaType MediaType) MediaUrl { //func (widget *GetWidgetDb) GetMediaUrl(mediaType MediaType) MediaUrl {
// var mediaUrl MediaUrl // var mediaUrl MediaUrl
// if mediaType == "background_url" { // if mediaType == "background_url" {

View File

@ -44,6 +44,13 @@ CREATE TABLE IF NOT EXISTS donats (
amount INTEGER NOT NULL, amount INTEGER NOT NULL,
donat_user TEXT NOT NULL, donat_user TEXT NOT NULL,
accepted BOOLEAN NOT NULL DEFAULT 'false',
show_name BOOLEAN NOT NULL DEFAULT 'true',
show_text BOOLEAN NOT NULL DEFAULT 'true',
play_content BOOLEAN NOT NULL DEFAULT 'true',
showed BOOLEAN NOT NULL DEFAULT 'false',
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
); );

View File

@ -421,3 +421,27 @@ WHERE
streamer_id = @streamer_id streamer_id = @streamer_id
AND created_at >= NOW() - INTERVAL '1 year'; AND created_at >= NOW() - INTERVAL '1 year';
` `
const GetLastModeration = `
SELECT
id,
target_id,
status,
text,
amount,
donat_user,
accepted,
show_name,
show_text,
play_content,
created_at,
updated_at
FROM
public.donats
WHERE
status = 'moderation' AND
streamer_id = @streamer_id
ORDER BY
updated_at DESC
LIMIT 1;
`

View File

@ -681,3 +681,41 @@ func (repoDonat *RepoDonat) GetDonationsSummary(
return summary, nil return summary, nil
} }
func (repoDonat *RepoDonat) GetDonatModeration(
ctx context.Context,
streamerID int,
) (model.DonationModeration, error) {
var donation model.DonationModeration
args := pgx.NamedArgs{
"streamer_id": streamerID,
}
row, err := repoDonat.db.SelectOne(ctx, sql.GetLastModeration, args)
if err != nil {
slog.Error("Failed to get donation", "error", err)
return model.DonationModeration{}, err
}
if row == nil {
return model.DonationModeration{}, nil
}
err = row.Scan(
&donation.ID,
&donation.TargetID,
&donation.Status,
&donation.Text,
&donation.Amount,
&donation.DonatUser,
&donation.Accepted,
&donation.ShowName,
&donation.ShowText,
&donation.PlayContent,
&donation.CreatedAt,
&donation.UpdatedAt,
)
if err != nil {
slog.Error("Failed to get latest donation in moderation", "error", err)
return model.DonationModeration{}, err
}
return donation, nil
}

View File

@ -492,3 +492,16 @@ func (donatService *ServiceDonat) GetDonationsStats(
return response, nil return response, nil
} }
func (donatService *ServiceDonat) GetDonatModeration(
ctx context.Context,
streamerID int,
) (model.DonationModeration, error) {
donation, err := donatService.donatRepo.GetDonatModeration(ctx, streamerID)
if err != nil {
slog.Error("Failed to get latest donation in moderation", "error", err)
return model.DonationModeration{}, err
}
return donation, nil
}