add filter by market id

This commit is contained in:
OneTap Technologies 2025-04-14 17:44:08 +03:00
parent d416a40cae
commit 1f154e9faf
11 changed files with 113 additions and 83 deletions

View File

@ -75,17 +75,17 @@ SELECT
FROM odds
WHERE is_active = true AND source = 'b365api';
-- name: GetRawOddsByID :one
-- name: GetRawOddsByMarketID :many
SELECT
id,
raw_odds,
fetched_at
FROM odds
WHERE
raw_odds @> $1::jsonb AND
market_id = $1 AND
is_active = true AND
source = 'b365api'
LIMIT 1;
LIMIT $2 OFFSET $3;
-- name: GetPrematchOddsByUpcomingID :many
SELECT

View File

@ -288,9 +288,9 @@ const docTemplate = `{
}
}
},
"/prematch/odds/raw/{raw_odds_id}": {
"/prematch/odds/raw/{market_id}": {
"get": {
"description": "Retrieve raw odds by raw odds ID",
"description": "Retrieve raw odds records using a Market ID",
"consumes": [
"application/json"
],
@ -300,12 +300,12 @@ const docTemplate = `{
"tags": [
"prematch"
],
"summary": "Retrieve raw odds by ID",
"summary": "Retrieve raw odds by Market ID",
"parameters": [
{
"type": "string",
"description": "Raw Odds ID",
"name": "raw_odds_id",
"description": "Market ID",
"name": "market_id",
"in": "path",
"required": true
}
@ -314,7 +314,10 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.RawOddsByID"
"type": "array",
"items": {
"$ref": "#/definitions/domain.RawOddsByMarketID"
}
}
},
"400": {
@ -761,12 +764,9 @@ const docTemplate = `{
}
}
},
"domain.RawOddsByID": {
"domain.RawOddsByMarketID": {
"type": "object",
"properties": {
"event_id": {
"type": "string"
},
"fetched_at": {
"type": "string"
},

View File

@ -280,9 +280,9 @@
}
}
},
"/prematch/odds/raw/{raw_odds_id}": {
"/prematch/odds/raw/{market_id}": {
"get": {
"description": "Retrieve raw odds by raw odds ID",
"description": "Retrieve raw odds records using a Market ID",
"consumes": [
"application/json"
],
@ -292,12 +292,12 @@
"tags": [
"prematch"
],
"summary": "Retrieve raw odds by ID",
"summary": "Retrieve raw odds by Market ID",
"parameters": [
{
"type": "string",
"description": "Raw Odds ID",
"name": "raw_odds_id",
"description": "Market ID",
"name": "market_id",
"in": "path",
"required": true
}
@ -306,7 +306,10 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/domain.RawOddsByID"
"type": "array",
"items": {
"$ref": "#/definitions/domain.RawOddsByMarketID"
}
}
},
"400": {
@ -753,12 +756,9 @@
}
}
},
"domain.RawOddsByID": {
"domain.RawOddsByMarketID": {
"type": "object",
"properties": {
"event_id": {
"type": "string"
},
"fetched_at": {
"type": "string"
},

View File

@ -33,10 +33,8 @@ definitions:
source:
type: string
type: object
domain.RawOddsByID:
domain.RawOddsByMarketID:
properties:
event_id:
type: string
fetched_at:
type: string
id:
@ -465,15 +463,15 @@ paths:
summary: Retrieve prematch odds for an event
tags:
- prematch
/prematch/odds/raw/{raw_odds_id}:
/prematch/odds/raw/{market_id}:
get:
consumes:
- application/json
description: Retrieve raw odds by raw odds ID
description: Retrieve raw odds records using a Market ID
parameters:
- description: Raw Odds ID
- description: Market ID
in: path
name: raw_odds_id
name: market_id
required: true
type: string
produces:
@ -482,7 +480,9 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/domain.RawOddsByID'
items:
$ref: '#/definitions/domain.RawOddsByMarketID'
type: array
"400":
description: Bad Request
schema:
@ -491,7 +491,7 @@ paths:
description: Internal Server Error
schema:
$ref: '#/definitions/response.APIResponse'
summary: Retrieve raw odds by ID
summary: Retrieve raw odds by Market ID
tags:
- prematch
/prematch/odds/upcoming/{upcoming_id}:

View File

@ -248,30 +248,49 @@ func (q *Queries) GetPrematchOddsByUpcomingID(ctx context.Context, arg GetPremat
return items, nil
}
const GetRawOddsByID = `-- name: GetRawOddsByID :one
const GetRawOddsByMarketID = `-- name: GetRawOddsByMarketID :many
SELECT
id,
raw_odds,
fetched_at
FROM odds
WHERE
raw_odds @> $1::jsonb AND
market_id = $1 AND
is_active = true AND
source = 'b365api'
LIMIT 1
LIMIT $2 OFFSET $3
`
type GetRawOddsByIDRow struct {
type GetRawOddsByMarketIDParams struct {
MarketID pgtype.Text
Limit int32
Offset int32
}
type GetRawOddsByMarketIDRow struct {
ID int32
RawOdds []byte
FetchedAt pgtype.Timestamp
}
func (q *Queries) GetRawOddsByID(ctx context.Context, dollar_1 []byte) (GetRawOddsByIDRow, error) {
row := q.db.QueryRow(ctx, GetRawOddsByID, dollar_1)
var i GetRawOddsByIDRow
err := row.Scan(&i.ID, &i.RawOdds, &i.FetchedAt)
return i, err
func (q *Queries) GetRawOddsByMarketID(ctx context.Context, arg GetRawOddsByMarketIDParams) ([]GetRawOddsByMarketIDRow, error) {
rows, err := q.db.Query(ctx, GetRawOddsByMarketID, arg.MarketID, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetRawOddsByMarketIDRow
for rows.Next() {
var i GetRawOddsByMarketIDRow
if err := rows.Scan(&i.ID, &i.RawOdds, &i.FetchedAt); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const InsertNonLiveOdd = `-- name: InsertNonLiveOdd :exec

View File

@ -38,9 +38,8 @@ type Odd struct {
Source string `json:"source"`
IsActive bool `json:"is_active"`
}
type RawOddsByID struct {
type RawOddsByMarketID struct {
ID int64 `json:"id"`
EventID string `json:"event_id"`
RawOdds []RawMessage `json:"raw_odds"`
FetchedAt time.Time `json:"fetched_at"`
}

View File

@ -3,6 +3,7 @@ package repository
import (
"context"
"encoding/json"
"fmt"
"os"
"strconv"
"time"
@ -175,21 +176,31 @@ func (s *Store) GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error) {
return domainOdds, nil
}
func (s *Store) GetRawOddsByID(ctx context.Context, rawOddsID string) (domain.RawOddsByID, error) {
jsonFilter := `[{"id":"` + rawOddsID + `"}]`
odd, err := s.queries.GetRawOddsByID(ctx, []byte(jsonFilter))
if err != nil {
return domain.RawOddsByID{}, err
func (s *Store) GetRawOddsByMarketID(ctx context.Context, rawOddsID string) (domain.RawOddsByMarketID, error) {
params := dbgen.GetRawOddsByMarketIDParams{
MarketID: pgtype.Text{String: rawOddsID, Valid: true},
Limit: 1,
Offset: 0,
}
rows, err := s.queries.GetRawOddsByMarketID(ctx, params)
if err != nil {
return domain.RawOddsByMarketID{}, err
}
if len(rows) == 0 {
return domain.RawOddsByMarketID{}, fmt.Errorf("no raw odds found for market_id: %s", rawOddsID)
}
row := rows[0]
var rawOdds []json.RawMessage
if err := json.Unmarshal(odd.RawOdds, &rawOdds); err != nil {
return domain.RawOddsByID{}, err
if err := json.Unmarshal(row.RawOdds, &rawOdds); err != nil {
return domain.RawOddsByMarketID{}, err
}
return domain.RawOddsByID{
ID: int64(odd.ID),
return domain.RawOddsByMarketID{
ID: int64(row.ID),
RawOdds: func() []domain.RawMessage {
converted := make([]domain.RawMessage, len(rawOdds))
for i, r := range rawOdds {
@ -197,19 +208,17 @@ func (s *Store) GetRawOddsByID(ctx context.Context, rawOddsID string) (domain.Ra
}
return converted
}(),
FetchedAt: odd.FetchedAt.Time,
FetchedAt: row.FetchedAt.Time,
}, nil
}
func (s *Store) GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit, offset int32) ([]domain.Odd, error) {
// Prepare query parameters
params := dbgen.GetPrematchOddsByUpcomingIDParams{
ID: upcomingID,
Limit: limit,
Offset: offset,
}
// Execute the query
odds, err := s.queries.GetPrematchOddsByUpcomingID(ctx, params)
if err != nil {
return nil, err

View File

@ -10,7 +10,7 @@ type Service interface {
FetchNonLiveOdds(ctx context.Context) error
GetPrematchOdds(ctx context.Context, eventID string) ([]domain.Odd, error)
GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, error)
GetRawOddsByID(ctx context.Context, rawOddsID string) ([]domain.RawOddsByID, error)
GetRawOddsByMarketID(ctx context.Context, marketID string) ([]domain.RawOddsByMarketID, error)
}

View File

@ -122,13 +122,15 @@ func (s *ServiceImpl) GetALLPrematchOdds(ctx context.Context) ([]domain.Odd, err
return s.store.GetALLPrematchOdds(ctx)
}
func (s *ServiceImpl) GetRawOddsByID(ctx context.Context, rawOddsID string) ([]domain.RawOddsByID, error) {
rawOdds, err := s.store.GetRawOddsByID(ctx, rawOddsID)
func (s *ServiceImpl) GetRawOddsByMarketID(ctx context.Context, marketID string) ([]domain.RawOddsByMarketID, error) {
rows, err := s.store.GetRawOddsByMarketID(ctx, marketID)
if err != nil {
return nil, err
}
return []domain.RawOddsByID{rawOdds}, nil
return []domain.RawOddsByMarketID{rows}, nil
}
func (s *ServiceImpl) GetPrematchOddsByUpcomingID(ctx context.Context, upcomingID string, limit, offset int32) ([]domain.Odd, error) {
return s.store.GetPrematchOddsByUpcomingID(ctx, upcomingID, limit, offset)
}

View File

@ -55,26 +55,27 @@ func GetALLPrematchOdds(logger *slog.Logger, prematchSvc *odds.ServiceImpl) fibe
return response.WriteJSON(c, fiber.StatusOK, "All prematch odds retrieved successfully", odds, nil)
}
}
// GetRawOddsByID
// @Summary Retrieve raw odds by ID
// @Description Retrieve raw odds by raw odds ID
// GetRawOddsByMarketID
// @Summary Retrieve raw odds by Market ID
// @Description Retrieve raw odds records using a Market ID
// @Tags prematch
// @Accept json
// @Produce json
// @Param raw_odds_id path string true "Raw Odds ID"
// @Success 200 {object} domain.RawOddsByID
// @Param market_id path string true "Market ID"
// @Success 200 {array} domain.RawOddsByMarketID
// @Failure 400 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /prematch/odds/raw/{raw_odds_id} [get]
func GetRawOddsByID(logger *slog.Logger, prematchSvc *odds.ServiceImpl) fiber.Handler {
// @Router /prematch/odds/raw/{market_id} [get]
func GetRawOddsByMarketID(logger *slog.Logger, prematchSvc *odds.ServiceImpl) fiber.Handler {
return func(c *fiber.Ctx) error {
rawOddsID := c.Params("raw_odds_id")
if rawOddsID == "" {
return response.WriteJSON(c, fiber.StatusBadRequest, "Missing raw_odds_id", nil, nil)
marketID := c.Params("market_id")
if marketID == "" {
return response.WriteJSON(c, fiber.StatusBadRequest, "Missing market_id", nil, nil)
}
rawOdds, err := prematchSvc.GetRawOddsByID(c.Context(), rawOddsID)
rawOdds, err := prematchSvc.GetRawOddsByMarketID(c.Context(), marketID)
if err != nil {
logger.Error("failed to fetch raw odds", "error", err)
return response.WriteJSON(c, fiber.StatusInternalServerError, "Failed to retrieve raw odds", nil, nil)
}

View File

@ -29,7 +29,7 @@ func (a *App) initAppRoutes() {
a.fiber.Get("/prematch/odds/:event_id", handlers.GetPrematchOdds(a.logger, a.prematchSvc))
a.fiber.Get("/prematch/odds", handlers.GetALLPrematchOdds(a.logger, a.prematchSvc))
a.fiber.Get("/prematch/odds/raw/:raw_odds_id", handlers.GetRawOddsByID(a.logger, a.prematchSvc))
a.fiber.Get("/prematch/odds/raw/:market_id", handlers.GetRawOddsByMarketID(a.logger, a.prematchSvc))
a.fiber.Get("/prematch/events/:id", handlers.GetUpcomingEventByID(a.logger, a.eventSvc))
a.fiber.Get("/prematch/events", handlers.GetAllUpcomingEvents(a.logger, a.eventSvc))