From 8232960f1a286b1e4ed06778785e5f853fc91f7c Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 26 Jul 2025 09:25:34 -0400 Subject: [PATCH 1/3] fix non contest activties appearing as such --- src/core/version.ts | 2 +- src/services/instance/instance.test.ts | 30 ++++++++++++++++++++++ src/services/instance/instance.ts | 8 +++--- src/services/player-instances/history.ts | 8 +++--- src/services/player-instances/instances.ts | 8 +++--- src/services/player.ts | 10 ++++---- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/core/version.ts b/src/core/version.ts index caacb13c..295498f8 100644 --- a/src/core/version.ts +++ b/src/core/version.ts @@ -1 +1 @@ -export const apiVersion = "1.3.2" +export const apiVersion = "1.3.3" diff --git a/src/services/instance/instance.test.ts b/src/services/instance/instance.test.ts index 425cebc7..87ee839b 100644 --- a/src/services/instance/instance.test.ts +++ b/src/services/instance/instance.test.ts @@ -22,6 +22,36 @@ describe("getInstance", () => { expect(parsed.success).toBe(true) } }) + describe("edge cases", () => { + it("is day one for day 1 clears on contest tdp", async () => { + const data = await getInstance("16321449037").catch(console.error) + const parsed = zInstance.safeParse(data) + if (!parsed.success) { + console.error(parsed.error.errors) + expect(parsed.error.errors).toEqual([]) + } else { + expect(parsed.success).toBe(true) + expect(parsed.data.isContest).toBe(true) + expect(parsed.data.isDayOne).toBe(true) + expect(parsed.data.isWeekOne).toBe(true) + } + }) + + it("is not contest or day one for day 1 clears on non-contest tdp", async () => { + const data = await getInstance("16322031067").catch(console.error) + + const parsed = zInstance.safeParse(data) + if (!parsed.success) { + console.error(parsed.error.errors) + expect(parsed.error.errors).toEqual([]) + } else { + expect(parsed.success).toBe(true) + expect(parsed.data.isContest).toBe(false) + expect(parsed.data.isDayOne).toBe(false) + expect(parsed.data.isWeekOne).toBe(true) + } + }) + }) }) describe("getInstanceExtended", () => { diff --git a/src/services/instance/instance.ts b/src/services/instance/instance.ts index b535063c..156e2628 100644 --- a/src/services/instance/instance.ts +++ b/src/services/instance/instance.ts @@ -22,13 +22,13 @@ export async function getInstance(instanceId: bigint | string): Promise $4" : ""} diff --git a/src/services/player-instances/instances.ts b/src/services/player-instances/instances.ts index 1bf45f78..d141f552 100644 --- a/src/services/player-instances/instances.ts +++ b/src/services/player-instances/instances.ts @@ -133,15 +133,15 @@ export async function getInstances({ season_id AS "season", duration AS "duration", platform_type AS "platformType", - date_completed < COALESCE(day_one_end, TIMESTAMP 'epoch') AS "isDayOne", - date_completed < COALESCE(contest_end, TIMESTAMP 'epoch') AS "isContest", + CASE WHEN av.is_world_first THEN date_completed < COALESCE(day_one_end, TIMESTAMP 'epoch') ELSE false END AS "isDayOne", + CASE WHEN av.is_world_first THEN date_completed < COALESCE(contest_end, TIMESTAMP 'epoch') ELSE false END AS "isContest", date_completed < COALESCE(week_one_end, TIMESTAMP 'epoch') AS "isWeekOne", b.instance_id IS NOT NULL AS "isBlacklisted", "_lateral".players AS "players" FROM _player_instances INNER JOIN instance USING (instance_id) - INNER JOIN activity_version USING (hash) - INNER JOIN activity_definition ON activity_definition.id = activity_version.activity_id + INNER JOIN activity_version av USING (hash) + INNER JOIN activity_definition ON activity_definition.id = av.activity_id LEFT JOIN blacklist_instance b USING (instance_id) LEFT JOIN LATERAL ( SELECT diff --git a/src/services/player.ts b/src/services/player.ts index 74567c20..c3c6916f 100644 --- a/src/services/player.ts +++ b/src/services/player.ts @@ -44,8 +44,8 @@ export const getPlayerActivityStats = async (membershipId: bigint | string) => { THEN JSONB_BUILD_OBJECT( 'instanceId', fastest.instance_id::text, 'hash', fastest.hash, - 'activityId', fastest_ah.activity_id, - 'versionId', fastest_ah.version_id, + 'activityId', av.activity_id, + 'versionId', av.version_id, 'completed', fastest.completed, 'playerCount', fastest.player_count, 'score', fastest.score, @@ -56,8 +56,8 @@ export const getPlayerActivityStats = async (membershipId: bigint | string) => { 'season', fastest.season_id, 'duration', fastest.duration, 'platformType', fastest.platform_type, - 'isDayOne', date_completed < COALESCE(day_one_end, TIMESTAMP 'epoch'), - 'isContest', date_completed < COALESCE(contest_end, TIMESTAMP 'epoch'), + 'isDayOne', CASE WHEN av.is_world_first THEN date_completed < COALESCE(day_one_end, TIMESTAMP 'epoch') ELSE false END, + 'isContest', CASE WHEN av.is_world_first THEN date_completed < COALESCE(contest_end, TIMESTAMP 'epoch') ELSE false END, 'isWeekOne', date_completed < COALESCE(week_one_end, TIMESTAMP 'epoch'), 'isBlacklisted', bi.instance_id IS NOT NULL ) @@ -68,7 +68,7 @@ export const getPlayerActivityStats = async (membershipId: bigint | string) => { AND player_stats.membership_id = $1::bigint LEFT JOIN instance fastest ON player_stats.fastest_instance_id = fastest.instance_id LEFT JOIN blacklist_instance bi ON player_stats.fastest_instance_id = bi.instance_id - LEFT JOIN activity_version fastest_ah ON fastest.hash = fastest_ah.hash + LEFT JOIN activity_version av ON fastest.hash = av.hash ORDER BY activity_definition.id`, { params: [membershipId], From 4818ae41a581e161b5e314dccbe93104cc34e189 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 26 Jul 2025 09:27:58 -0400 Subject: [PATCH 2/3] docs --- open-api/openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/open-api/openapi.json b/open-api/openapi.json index be115a2c..1cb7f521 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -3,7 +3,7 @@ "info": { "title": "RaidHub API", "description": "The Semi-public API for RaidHub", - "version": "1.3.2", + "version": "1.3.3", "contact": { "name": "RaidHub Admin", "email": "admin@raidhub.io" From a10ae34b3fc8b58971fef8625cb81583a4584a90 Mon Sep 17 00:00:00 2001 From: owen Date: Sat, 26 Jul 2025 09:36:37 -0400 Subject: [PATCH 3/3] minor fix --- open-api/openapi.json | 7 ++++++- src/schema/components/InstanceStanding.ts | 3 ++- src/services/atlas/atlas.test.ts | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/open-api/openapi.json b/open-api/openapi.json index 1cb7f521..d8115b1d 100644 --- a/open-api/openapi.json +++ b/open-api/openapi.json @@ -500,7 +500,12 @@ }, "reportSource": { "type": "string", - "enum": ["Manual", "CheatCheck", "WebReport"] + "enum": [ + "Manual", + "CheatCheck", + "WebReport", + "BlacklistedPlayerCascade" + ] }, "reportId": { "type": "integer", diff --git a/src/schema/components/InstanceStanding.ts b/src/schema/components/InstanceStanding.ts index 91fd4d36..cf5b5354 100644 --- a/src/schema/components/InstanceStanding.ts +++ b/src/schema/components/InstanceStanding.ts @@ -6,7 +6,8 @@ import { zPlayerInfo } from "./PlayerInfo" enum ReportSource { Manual = "Manual", CheatCheck = "CheatCheck", - WebReport = "WebReport" + WebReport = "WebReport", + BlacklistedPlayerCascade = "BlacklistedPlayerCascade" } enum CheatFlagIndex { diff --git a/src/services/atlas/atlas.test.ts b/src/services/atlas/atlas.test.ts index e676b8f4..0f6d3836 100644 --- a/src/services/atlas/atlas.test.ts +++ b/src/services/atlas/atlas.test.ts @@ -112,6 +112,6 @@ describe("getAtlasStatus no mock", () => { const result = await getAtlasStatus() expect(result.isCrawling).toBeTrue() - expect(result.lag).toBeWithin(25, 45) + expect(result.lag).toBeWithin(15, 60) }) })