---
# System prepended metadata

title: Source Management暨混水模組設計(beta)

---

# Source Management暨混水模組設計(beta)
操盤自有的賽事＆玩法＆賠率管理模組
![](https://i.imgur.com/B6lMXcL.jpg)


把Source Fetch拆開，解耦目前串接RTI碰到的問題，不管數據從哪來怎麼來，都讓Source Management不需要太關注

Source Management與混水模組組合起來，需要具備的作用
- 賽事資料的管理
- 多數據源賠率資料的管理
- 能產出Ｍ水，並透過Kafka推送最新資料
- 具備Query功能(先做function能程式內部使用)

> *兩個模組在程式實作面怎麼拆分，需要再討論*

## Input Function
可以給資料收集模組呼叫的function

### Match 賽事
```
新增賽事
func MatchCreate(MatchInputEntity) {   }
func MatchMultipleCreate(MatchInputEntity[]) {   }

賽事資訊更新，目前有的情境：比賽節數變化、進球、紅牌
func MatchUpdate(MatchInputEntity) {   }
func MatchMultipleUpdate(MatchInputEntity[]) {   }
```

### Market 玩法、賠率
要記錄多bookmaker的數據
```
func MarketUpdate(MarketInputEntity) {   }
func MarketMultipleUpdate(MarketInputEntity[]) {   }
```

### Event 事件
先預留著，等RTI完成事件後再接入
這邊的事件，是包括動態圖中細項的事件，例如換人、角球
```
func MatchEventCreate(EventInfo) {   }
func MatchEventMultipleCreate(EventInfo[]) {   }
```
### Data Format
#### MatchInputEntity
```
type MatchInputEntity {
    "id": "numberStr",
    "home": {
        "name": "str",
        "score": "numberStr",
        "redCard": "numberStr"
    },
    "away": {
        "name": "str",
        "score": "numberStr",
        "redCard": "numberStr"
    },
    "status": {
        "phase": "str", // NOT_STARTED, FIRST_HALF, HALFTIME, SECOND_HALF, ENDED
        "bookmaker": "str",
        "scheduledTime": "2022-12-22T00:30:00Z", // 賽事開打時間
        "phaseStartTime": "2022-12-22T00:30:00Z", // 節數開打時間
        "injuryTime": "numberStr", // 傷停補時
    }
}
```
#### MarketInputEntity
```
type MarketInputEntity {
  "id": "numberStr", //matchID
  "bookmaker": "str" //數據源
  "markets": [
      {
          "marketID": "numberStr",
          "isPause": false,
          "lines": [
              {
                  "condition": "str",
                  "status": "str", // Open, Suspended, Closed
                  "alias": "str", // Main, FirstSub, SecondSub
                  "outcomes": [
                      {
                          "id": "numberStr",
                          "odd": "numberStr"
                      }
                  ]
              }
          ]
      }
  ]
}
```
## Kafka Data
### Internal
分為Match, Market兩種類型

因為系統會將賽事分為InPlay, NotStarted, Finish三種類型
友善使用，將把三種類型的賽事通知分到三個Topic

Client Center在訂閱Kafka時，可以用下面的條件區分PreMatch, EarlyMatch
PreMatch => NotStarted && ScheduleTime is Today
EarMatch => NotStarted && ScheduleTime in 搜尋的日期區間

### External
分為Match, Market, Lines三個Topic

### TODO: Kafka Data Format
```
```

## Query Function
### 賽事資訊
```
func GetMatch(MatchId[])
func GetMatch(Tournement[], startTime, endTime)
```
### 賠率資訊
```
func GetMarket(MatchID[]) MatchInfo[]

//可以指定抓取不同的bookmaker數據
//MatchID這層的Bookmaker為此次請求的預設數據源，在沒有指定玩法要用的數據源時
//特定某個玩法，要與外層的數據源不同時，則使用Market這層的bookmaker
func GetMarket({MatchID, Bookmaker, {MarketID, Bookmaker}[]}[]) MatchInfo[]

範例：
1x2使用B數據，AH(16)使用C數據，OU(18)使用D數據
{
  "MatchID":"123456",
  "Bookmaker": "B",
  "Markets":[
    {
      "MarketID":16,
      "Bookmaker": "C"
    },
    {
      "MarketID":18,
      "Bookmaker": "D"
    }
  ]
}
```

### TODO: Data Format
```
```


## 可能要開的table
- Match
- Market 
- Match/Bookmaker MatchID Mapping TABLE
- Tournement多語系對照表
- TeamName多語系對照表
- MarketID多語系對照表
- OutcomeID對照表