# Source Management暨混水模組設計(beta)
操盤自有的賽事&玩法&賠率管理模組

把Source Fetch拆開,解耦目前串接RTI碰到的問題,不管數據從哪來怎麼來,都讓Source Management不需要太關注
Source Management與混水模組組合起來,需要具備的作用
- 賽事資料的管理
- 多數據源賠率資料的管理
- 能產出M水,並透過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對照表