move overall stats to its own service file
This commit is contained in:
@@ -5,6 +5,7 @@ import { database, Character, Game, Pick, App } from './db'
|
||||
import { OrderByParser, FilterParser } from './tokenizer'
|
||||
import { addGameApis } from './gameservice'
|
||||
import { addCharacterApis } from './characterservice'
|
||||
import { addRushStatsApis } from './rushstatsservice'
|
||||
|
||||
const app = express()
|
||||
const jsonParser = json()
|
||||
@@ -12,125 +13,8 @@ const port = 3001
|
||||
|
||||
addGameApis(app, jsonParser)
|
||||
addCharacterApis(app, jsonParser)
|
||||
addRushStatsApis(app, jsonParser)
|
||||
|
||||
app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => {
|
||||
const monthId = req.body.monthId
|
||||
let startSeconds = 0
|
||||
let endSeconds = Number.MAX_SAFE_INTEGER
|
||||
|
||||
if (monthId != -1) {
|
||||
const month = monthId % 12
|
||||
const year = Math.floor(monthId / 12) + 2023
|
||||
|
||||
const startDate = new Date(year, month, 1)
|
||||
const endDate = new Date(year, month + 1, -1)
|
||||
|
||||
startSeconds = startDate.getTime() / 1000
|
||||
endSeconds = endDate.getTime() / 1000
|
||||
}
|
||||
|
||||
const serverGameStats = await database.query(
|
||||
'SELECT ' +
|
||||
'COUNT(*) as TotalGames, ' +
|
||||
'SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as Complete, ' +
|
||||
'SUM(CASE WHEN status = "Postponed" THEN 1 ELSE 0 END) as Postponed, ' +
|
||||
'SUM(CASE WHEN status = "Pending" THEN 1 ELSE 0 END) as Pending, ' +
|
||||
'SUM(CASE WHEN event = "TRUE" THEN 1 ELSE 0 END) as Events, ' +
|
||||
'SUM(CASE WHEN fix = "TRUE" THEN 1 ELSE 0 END) as Fixes, ' +
|
||||
'SUM(payoutEB) as TotalEB, ' +
|
||||
'SUM(payoutIP) as TotalIP, ' +
|
||||
'SUM(payoutEB) / SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as AverageEB, ' +
|
||||
'SUM(payoutIP) / SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as AverageIP ' +
|
||||
'FROM Games WHERE postdate BETWEEN :startSeconds AND :endSeconds',
|
||||
{
|
||||
type: QueryTypes.SELECT,
|
||||
replacements: {
|
||||
startSeconds,
|
||||
endSeconds
|
||||
}
|
||||
}
|
||||
)
|
||||
res.send(serverGameStats[0])
|
||||
})
|
||||
|
||||
app.post('/api/serverstats/rolestats', jsonParser, async (req, res) => {
|
||||
const monthId = req.body.monthId
|
||||
|
||||
let startSeconds = 0
|
||||
let endSeconds = Number.MAX_SAFE_INTEGER
|
||||
|
||||
if (monthId != -1) {
|
||||
const month = monthId % 12
|
||||
const year = Math.floor(monthId / 12) + 2023
|
||||
|
||||
const startDate = new Date(year, month, 1)
|
||||
const endDate = new Date(year, month + 1, -1)
|
||||
|
||||
startSeconds = startDate.getTime() / 1000
|
||||
endSeconds = endDate.getTime() / 1000
|
||||
}
|
||||
|
||||
const games = await Game.findAll({
|
||||
include: [
|
||||
{ model: Character, as: 'characterPickedForGame' },
|
||||
{ model: Character, as: 'characterAppliedForGame' }
|
||||
],
|
||||
where: { postdate: { [Op.between]: [startSeconds, endSeconds] } }
|
||||
})
|
||||
|
||||
// count active roles
|
||||
let activeCharacters = new Map()
|
||||
let pickedCharacterCount = new Map()
|
||||
let appedCharacterCount = new Map()
|
||||
|
||||
games.forEach((game, gameNum) => {
|
||||
const picks = game.dataValues.characterPickedForGame
|
||||
const appls = game.dataValues.characterAppliedForGame
|
||||
|
||||
picks.forEach((character, characterNum) => {
|
||||
const role = character.dataValues.role
|
||||
// Count role application
|
||||
pickedCharacterCount.set(role, (pickedCharacterCount.get(role) || 0) + 1)
|
||||
})
|
||||
|
||||
appls.forEach((character, characterNum) => {
|
||||
const role = character.dataValues.role
|
||||
const charId = character.dataValues.id
|
||||
// Add apllied characters to active list
|
||||
if (!activeCharacters.has(role)) {
|
||||
activeCharacters.set(role, new Set())
|
||||
}
|
||||
activeCharacters.get(role).add(charId)
|
||||
// Count role application
|
||||
appedCharacterCount.set(role, (appedCharacterCount.get(role) || 0) + 1)
|
||||
})
|
||||
})
|
||||
|
||||
const roleNames = [
|
||||
'Fixer',
|
||||
'Tech',
|
||||
'Medtech',
|
||||
'Media',
|
||||
'Netrunner',
|
||||
'Solo',
|
||||
'Nomad',
|
||||
'Exec',
|
||||
'Lawman',
|
||||
'Rocker'
|
||||
]
|
||||
|
||||
const result = {}
|
||||
|
||||
roleNames.forEach((roleName) => {
|
||||
result[roleName] = {
|
||||
apps: appedCharacterCount.get(roleName) || 0,
|
||||
picks: pickedCharacterCount.get(roleName) || 0,
|
||||
active: activeCharacters.has(roleName) ? activeCharacters.get(roleName).size : 0
|
||||
}
|
||||
})
|
||||
|
||||
res.send(result)
|
||||
})
|
||||
|
||||
app.use(express.static(__dirname + '/frontend'))
|
||||
app.use('/', (req, res) => {
|
||||
|
||||
@@ -88,7 +88,7 @@ export function addCharacterApis(app, jsonParser) {
|
||||
if (gameHistory) {
|
||||
res.send(gameHistory)
|
||||
} else {
|
||||
res.status(404).send("Could nor find character.")
|
||||
res.status(404).send('Could nor find character.')
|
||||
}
|
||||
} catch (e) {
|
||||
res.status(500).send(e)
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
import { Sequelize, Model, DataTypes } from 'sequelize'
|
||||
|
||||
export type RoleName =
|
||||
| 'Fixer'
|
||||
| 'Tech'
|
||||
| 'Medtech'
|
||||
| 'Media'
|
||||
| 'Netrunner'
|
||||
| 'Solo'
|
||||
| 'Nomad'
|
||||
| 'Exec'
|
||||
| 'Lawman'
|
||||
| 'Rocker'
|
||||
|
||||
export const roleNames: RoleName[] = [
|
||||
'Fixer',
|
||||
'Tech',
|
||||
'Medtech',
|
||||
'Media',
|
||||
'Netrunner',
|
||||
'Solo',
|
||||
'Nomad',
|
||||
'Exec',
|
||||
'Lawman',
|
||||
'Rocker'
|
||||
]
|
||||
|
||||
const databasePath = './testdb.db'
|
||||
|
||||
export const database = new Sequelize({
|
||||
|
||||
@@ -51,8 +51,9 @@ export function addGameApis(app, jsonParser) {
|
||||
app.post('/api/game/:gameId/apps', async (req, res) => {
|
||||
try {
|
||||
const apps = await App.findAll({
|
||||
include: { model: Character, as: "appliedCharacter"},
|
||||
where: { gameId: req.params['gameId'] } })
|
||||
include: { model: Character, as: 'appliedCharacter' },
|
||||
where: { gameId: req.params['gameId'] }
|
||||
})
|
||||
if (!apps) {
|
||||
res.status(404).send('Apps not found.')
|
||||
} else {
|
||||
@@ -66,8 +67,9 @@ export function addGameApis(app, jsonParser) {
|
||||
app.post('/api/game/:gameId/picks', async (req, res) => {
|
||||
try {
|
||||
const picks = await Pick.findAll({
|
||||
include: { model: Character, as: "pickedCharacter"},
|
||||
where: { gameId: req.params['gameId'] } })
|
||||
include: { model: Character, as: 'pickedCharacter' },
|
||||
where: { gameId: req.params['gameId'] }
|
||||
})
|
||||
if (!picks) {
|
||||
res.status(404).send('Picks not found')
|
||||
} else {
|
||||
|
||||
115
backend/src/rushstatsservice.ts
Normal file
115
backend/src/rushstatsservice.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { database, Character, Game, Pick, App, roleNames } from './db'
|
||||
import { Op, QueryTypes } from 'sequelize'
|
||||
|
||||
const serverGameStatsQuery =
|
||||
'SELECT ' +
|
||||
'COUNT(*) as TotalGames, ' +
|
||||
'SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as Complete, ' +
|
||||
'SUM(CASE WHEN status = "Postponed" THEN 1 ELSE 0 END) as Postponed, ' +
|
||||
'SUM(CASE WHEN status = "Pending" THEN 1 ELSE 0 END) as Pending, ' +
|
||||
'SUM(CASE WHEN event = "TRUE" THEN 1 ELSE 0 END) as Events, ' +
|
||||
'SUM(CASE WHEN fix = "TRUE" THEN 1 ELSE 0 END) as Fixes, ' +
|
||||
'SUM(payoutEB) as TotalEB, ' +
|
||||
'SUM(payoutIP) as TotalIP, ' +
|
||||
'SUM(payoutEB) / SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as AverageEB, ' +
|
||||
'SUM(payoutIP) / SUM(CASE WHEN status = "Complete" THEN 1 ELSE 0 END) as AverageIP ' +
|
||||
'FROM Games WHERE postdate BETWEEN :startSeconds AND :endSeconds'
|
||||
|
||||
const startingYear = 2023
|
||||
|
||||
function getMonthNumber(monthId: number): number {
|
||||
return monthId % 12
|
||||
}
|
||||
|
||||
function getYearNumber(monthId: number): number {
|
||||
return Math.floor(monthId / 12 + startingYear)
|
||||
}
|
||||
|
||||
function monthIdToStartSeconds(monthId: number): number {
|
||||
if (monthId) {
|
||||
const yearNumber = getYearNumber(monthId)
|
||||
const monthNumber = getMonthNumber(monthId)
|
||||
return new Date(yearNumber, monthNumber, 1).getTime() / 1000
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function monthIdToEndSeconds(monthId: number): number {
|
||||
if (monthId) {
|
||||
const yearNumber = getYearNumber(monthId)
|
||||
const monthNumber = getMonthNumber(monthId)
|
||||
return new Date(yearNumber, monthNumber + 1, -1).getTime() / 1000
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
export function addRushStatsApis(app, jsonParser) {
|
||||
app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => {
|
||||
const monthId = req.body.monthId
|
||||
let startSeconds = monthIdToStartSeconds(monthId)
|
||||
let endSeconds = monthIdToEndSeconds(monthId)
|
||||
|
||||
const serverGameStats = await database.query(serverGameStatsQuery, {
|
||||
type: QueryTypes.SELECT,
|
||||
replacements: {
|
||||
startSeconds,
|
||||
endSeconds
|
||||
}
|
||||
})
|
||||
res.send(serverGameStats[0])
|
||||
})
|
||||
|
||||
app.post('/api/serverstats/rolestats', jsonParser, async (req, res) => {
|
||||
const monthId = req.body.monthId
|
||||
let startSeconds = monthIdToStartSeconds(monthId)
|
||||
let endSeconds = monthIdToEndSeconds(monthId)
|
||||
|
||||
const games = await Game.findAll({
|
||||
include: [
|
||||
{ model: Character, as: 'characterPickedForGame' },
|
||||
{ model: Character, as: 'characterAppliedForGame' }
|
||||
],
|
||||
where: { postdate: { [Op.between]: [startSeconds, endSeconds] } }
|
||||
})
|
||||
|
||||
// count active roles
|
||||
let activeCharacters = new Map()
|
||||
let pickedCharacterCount = new Map()
|
||||
let appedCharacterCount = new Map()
|
||||
|
||||
games.forEach((game, gameNum) => {
|
||||
const picks = game.dataValues.characterPickedForGame
|
||||
const appls = game.dataValues.characterAppliedForGame
|
||||
|
||||
picks.forEach((character, characterNum) => {
|
||||
const role = character.dataValues.role
|
||||
// Count role application
|
||||
pickedCharacterCount.set(role, (pickedCharacterCount.get(role) || 0) + 1)
|
||||
})
|
||||
|
||||
appls.forEach((character, characterNum) => {
|
||||
const role = character.dataValues.role
|
||||
const charId = character.dataValues.id
|
||||
// Add apllied characters to active list
|
||||
if (!activeCharacters.has(role)) {
|
||||
activeCharacters.set(role, new Set())
|
||||
}
|
||||
activeCharacters.get(role).add(charId)
|
||||
// Count role application
|
||||
appedCharacterCount.set(role, (appedCharacterCount.get(role) || 0) + 1)
|
||||
})
|
||||
})
|
||||
|
||||
const result = {}
|
||||
|
||||
roleNames.forEach((roleName) => {
|
||||
result[roleName] = {
|
||||
apps: appedCharacterCount.get(roleName) || 0,
|
||||
picks: pickedCharacterCount.get(roleName) || 0,
|
||||
active: activeCharacters.has(roleName) ? activeCharacters.get(roleName).size : 0
|
||||
}
|
||||
})
|
||||
|
||||
res.send(result)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user