Skip to content

Commit 590a749

Browse files
authored
Merge pull request #326 from TaloDev/continuity
Add continuity middleware + health check api
2 parents 9d5f1a6 + e9ca6f7 commit 590a749

17 files changed

+201
-27
lines changed

src/config/api-routes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Koa, { Context, Next } from 'koa'
22
import { service } from 'koa-clay'
3+
import HealthCheckAPIService from '../services/api/health-check-api.service'
34
import GameFeedbackAPIService from '../services/api/game-feedback-api.service'
45
import GameConfigAPIService from '../services/api/game-config-api.service'
56
import GameStatAPIService from '../services/api/game-stat-api.service'
@@ -13,6 +14,7 @@ import { apiRouteAuthMiddleware, getRouteInfo } from '../middlewares/route-middl
1314
import apiKeyMiddleware from '../middlewares/api-key-middleware'
1415
import playerAuthMiddleware from '../middlewares/player-auth-middleware'
1516
import PlayerAuthAPIService from '../services/api/player-auth-api.service'
17+
import continunityMiddleware from '../middlewares/continunity-middleware'
1618

1719
export default (app: Koa) => {
1820
app.use(apiKeyMiddleware)
@@ -27,7 +29,9 @@ export default (app: Koa) => {
2729

2830
app.use(currentPlayerMiddleware)
2931
app.use(playerAuthMiddleware)
32+
app.use(continunityMiddleware)
3033

34+
app.use(service('/v1/health-check', new HealthCheckAPIService()))
3135
app.use(service('/v1/game-feedback', new GameFeedbackAPIService()))
3236
app.use(service('/v1/game-config', new GameConfigAPIService()))
3337
app.use(service('/v1/game-stats', new GameStatAPIService()))

src/entities/api-key.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import Game from './game'
33
import User from './user'
44

55
export enum APIKeyScope {
6+
WRITE_CONTINUITY_REQUESTS = 'write:continuityRequests',
67
READ_GAME_FEEDBACK = 'read:gameFeedback',
78
WRITE_GAME_FEEDBACK = 'write:gameFeedback',
89
READ_GAME_CONFIG = 'read:gameConfig',
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { isValid } from 'date-fns'
2+
import { Context, Next } from 'koa'
3+
import { APIKeyScope } from '../entities/api-key'
4+
import { isAPIRoute } from './route-middleware'
5+
import checkScope from '../policies/checkScope'
6+
7+
export default async (ctx: Context, next: Next): Promise<void> => {
8+
if (isAPIRoute(ctx) && checkScope(ctx.state.key, APIKeyScope.WRITE_CONTINUITY_REQUESTS)) {
9+
const header = ctx.headers['x-talo-continuity-timestamp']
10+
11+
if (header) {
12+
const date = new Date(Number(header))
13+
if (isValid(date)) {
14+
ctx.state.continuityDate = date
15+
}
16+
}
17+
}
18+
19+
await next()
20+
}

src/migrations/20210725211129InitialMigration.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ export class InitialMigration extends Migration {
2626
this.addSql('create table `player_alias` (`id` int unsigned not null auto_increment primary key, `service` varchar(255) not null, `identifier` varchar(255) not null, `player_id` varchar(255) null, `created_at` datetime not null, `updated_at` datetime not null) default character set utf8mb4 engine = InnoDB')
2727
this.addSql('alter table `player_alias` add index `player_alias_player_id_index`(`player_id`)')
2828

29-
this.addSql('create table `event` (`id` int unsigned not null auto_increment primary key, `name` varchar(255) not null, `props` json not null, `game_id` int(11) unsigned not null, `player_alias_id` int(11) unsigned not null, `created_at` datetime not null, `updated_at` datetime not null) default character set utf8mb4 engine = InnoDB')
30-
this.addSql('alter table `event` add index `event_game_id_index`(`game_id`)')
31-
this.addSql('alter table `event` add index `event_player_alias_id_index`(`player_alias_id`)')
32-
3329
this.addSql('create table `apikey` (`id` int unsigned not null auto_increment primary key, `scopes` text not null, `game_id` int(11) unsigned not null, `created_by_user_id` int(11) unsigned not null, `created_at` datetime not null, `revoked_at` datetime null) default character set utf8mb4 engine = InnoDB')
3430
this.addSql('alter table `apikey` add index `apikey_game_id_index`(`game_id`)')
3531
this.addSql('alter table `apikey` add index `apikey_created_by_user_id_index`(`created_by_user_id`)')
@@ -46,9 +42,6 @@ export class InitialMigration extends Migration {
4642

4743
this.addSql('alter table `player_alias` add constraint `player_alias_player_id_foreign` foreign key (`player_id`) references `player` (`id`) on delete cascade')
4844

49-
this.addSql('alter table `event` add constraint `event_game_id_foreign` foreign key (`game_id`) references `game` (`id`) on update cascade')
50-
this.addSql('alter table `event` add constraint `event_player_alias_id_foreign` foreign key (`player_alias_id`) references `player_alias` (`id`) on update cascade')
51-
5245
this.addSql('alter table `apikey` add constraint `apikey_game_id_foreign` foreign key (`game_id`) references `game` (`id`) on update cascade')
5346
this.addSql('alter table `apikey` add constraint `apikey_created_by_user_id_foreign` foreign key (`created_by_user_id`) references `user` (`id`) on update cascade')
5447
}

src/migrations/20211221195514CascadeDeletePlayerAliasEvents.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/migrations/index.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { CreateDataExportsTable } from './20210926160859CreateDataExportsTable'
33
import { CreateLeaderboardsTable } from './20211107233610CreateLeaderboardsTable'
44
import { CreateUserTwoFactorAuthTable } from './20211205171927CreateUserTwoFactorAuthTable'
55
import { CreateUserRecoveryCodeTable } from './20211209003017CreateUserRecoveryCodeTable'
6-
import { CascadeDeletePlayerAliasEvents } from './20211221195514CascadeDeletePlayerAliasEvents'
76
import { AddLeaderboardEntryHiddenColumn } from './20211224154919AddLeaderboardEntryHiddenColumn'
87
import { CreateGameSavesTable } from './20220109144435CreateGameSavesTable'
98
import { CreateGameActivitiesTable } from './20220125220401CreateGameActivitiesTable'
@@ -49,10 +48,6 @@ export default [
4948
name: 'CreateUserRecoveryCodeTable',
5049
class: CreateUserRecoveryCodeTable
5150
},
52-
{
53-
name: 'CascadeDeletePlayerAliasEvents',
54-
class: CascadeDeletePlayerAliasEvents
55-
},
5651
{
5752
name: 'AddLeaderboardEntryHiddenColumn',
5853
class: AddLeaderboardEntryHiddenColumn

src/services/api/game-feedback-api.service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ export default class GameFeedbackAPIService extends APIService {
4040
const feedback = new GameFeedback(category, req.ctx.state.playerAlias)
4141
feedback.comment = comment
4242
feedback.anonymised = category.anonymised
43+
if (req.ctx.state.continuityDate) {
44+
feedback.createdAt = req.ctx.state.continuityDate
45+
}
4346

4447
await em.persistAndFlush(feedback)
4548

src/services/api/game-stat-api.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export default class GameStatAPIService extends APIService {
5252

5353
if (!playerStat) {
5454
playerStat = new PlayerGameStat(req.ctx.state.player, req.ctx.state.stat)
55+
if (req.ctx.state.continuityDate) {
56+
playerStat.createdAt = req.ctx.state.continuityDate
57+
}
58+
5559
em.persist(playerStat)
5660
}
5761

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Response, Routes } from 'koa-clay'
2+
import APIService from './api-service'
3+
4+
@Routes([
5+
{
6+
method: 'GET'
7+
}
8+
])
9+
export default class HealthCheckAPIService extends APIService {
10+
async index(): Promise<Response> {
11+
return {
12+
status: 204
13+
}
14+
}
15+
}

src/services/api/leaderboard-api.service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export default class LeaderboardAPIService extends APIService {
3737
const entry = new LeaderboardEntry(req.ctx.state.leaderboard)
3838
entry.playerAlias = req.ctx.state.playerAlias
3939
entry.score = req.body.score
40+
if (req.ctx.state.continuityDate) {
41+
entry.createdAt = req.ctx.state.continuityDate
42+
}
4043

4144
await em.persistAndFlush(entry)
4245

@@ -67,7 +70,7 @@ export default class LeaderboardAPIService extends APIService {
6770

6871
if ((leaderboard.sortMode === LeaderboardSortMode.ASC && score < entry.score) || (leaderboard.sortMode === LeaderboardSortMode.DESC && score > entry.score)) {
6972
entry.score = score
70-
entry.createdAt = new Date()
73+
entry.createdAt = req.ctx.state.continuityDate ?? new Date()
7174
await em.flush()
7275

7376
updated = true

0 commit comments

Comments
 (0)