mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-25 23:18:51 -07:00
[api] add xp boost stub endpoint
This commit is contained in:
@@ -326,6 +326,24 @@ export const ProgressionEventRecordDto = z.object({
|
|||||||
LimitedRewardCollectionState: z.int(),
|
LimitedRewardCollectionState: z.int(),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One XP boost a player bought and has running, as `GET /api/purchasableXpBoosts/activations`
|
||||||
|
* lists it. Documented from the reference shape; nothing here sells or stores boosts yet.
|
||||||
|
*/
|
||||||
|
export const XpBoostActivationDto = z.object({
|
||||||
|
PurchasableXpBoostLedgerEntryId: z.int().describe('The purchase this activation came from'),
|
||||||
|
PurchasableXpBoostId: z.string().describe('GUID of the boost product bought'),
|
||||||
|
XpMultiplier: z.number().describe('XP is multiplied by this while the boost runs, e.g. 2.0'),
|
||||||
|
StartTime: z.string().describe('ISO-8601 UTC'),
|
||||||
|
EndTime: z.string().describe('ISO-8601 UTC'),
|
||||||
|
})
|
||||||
|
|
||||||
|
/** `GET /api/purchasableXpBoosts/activations` — a paged list of the caller's active boosts. */
|
||||||
|
export const XpBoostActivationsResponse = z.object({
|
||||||
|
Results: XpBoostActivationDto.array(),
|
||||||
|
TotalResults: z.int().describe('The number of entries in `Results`'),
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The form body of `POST /api/PlayerCheer/v1/create`. Nothing here is stored beyond the
|
* The form body of `POST /api/PlayerCheer/v1/create`. Nothing here is stored beyond the
|
||||||
* counter the cheer increments: `Anonymous` is spent on the notification it triggers and
|
* counter the cheer increments: `Anonymous` is spent on the notification it triggers and
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import {
|
|||||||
ReputationDto,
|
ReputationDto,
|
||||||
SetSelectedCheerRequest,
|
SetSelectedCheerRequest,
|
||||||
UNAUTHORIZED_RESPONSE,
|
UNAUTHORIZED_RESPONSE,
|
||||||
|
XpBoostActivationsResponse,
|
||||||
} from '../openapi'
|
} from '../openapi'
|
||||||
import {
|
import {
|
||||||
addCheer,
|
addCheer,
|
||||||
@@ -672,3 +673,27 @@ export const progressionRoutes = new Hono<App>({ strict: false })
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The XP boosts the caller has bought and has running — the client multiplies the XP it
|
||||||
|
// shows by them and draws a timer for each.
|
||||||
|
//
|
||||||
|
// STUB: always the empty page. Nothing sells boosts yet, so nobody has one running. No
|
||||||
|
// auth while the answer is the same for everybody, like `xpEarnedToday` above; it will
|
||||||
|
// need the caller once it is real, since the path names no player.
|
||||||
|
.get(
|
||||||
|
'/api/purchasableXpBoosts/activations',
|
||||||
|
describeRoute({
|
||||||
|
tags: ['Progression'],
|
||||||
|
summary: 'The caller’s active XP boosts (stub)',
|
||||||
|
description:
|
||||||
|
'The XP boosts the caller has running, as `{ Results, TotalResults }`. Always the ' +
|
||||||
|
'empty page (`{ "Results": [], "TotalResults": 0 }`) — nothing on this server sells ' +
|
||||||
|
'boosts yet. Each entry, once there are any, names the purchase ' +
|
||||||
|
'(`PurchasableXpBoostLedgerEntryId`), the boost bought (`PurchasableXpBoostId`), its ' +
|
||||||
|
'`XpMultiplier`, and when it runs (`StartTime`/`EndTime`, ISO-8601 UTC).',
|
||||||
|
responses: {
|
||||||
|
200: json(XpBoostActivationsResponse, 'Always `{ "Results": [], "TotalResults": 0 }`'),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
(c) => c.json({ Results: [], TotalResults: 0 })
|
||||||
|
)
|
||||||
|
|||||||
@@ -2144,6 +2144,12 @@ describe('public endpoints', () => {
|
|||||||
expect(await other.json()).toMatchObject({ ProgressionEventId: 7 })
|
expect(await other.json()).toMatchObject({ ProgressionEventId: 7 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('GET /api/purchasableXpBoosts/activations is the empty page', async () => {
|
||||||
|
const res = await exports.default.fetch(`${ORIGIN}/api/purchasableXpBoosts/activations`)
|
||||||
|
expect(res.status).toBe(200)
|
||||||
|
expect(await res.json()).toStrictEqual({ Results: [], TotalResults: 0 })
|
||||||
|
})
|
||||||
|
|
||||||
test('GET /api/rooms/v1/filters returns an object with filter arrays', async () => {
|
test('GET /api/rooms/v1/filters returns an object with filter arrays', async () => {
|
||||||
const res = await exports.default.fetch(`${ORIGIN}/api/rooms/v1/filters`)
|
const res = await exports.default.fetch(`${ORIGIN}/api/rooms/v1/filters`)
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
@@ -10247,6 +10253,7 @@ describe('openapi', () => {
|
|||||||
'GET /api/progressionEvents/active',
|
'GET /api/progressionEvents/active',
|
||||||
'GET /api/progressionEvents/event/{id}',
|
'GET /api/progressionEvents/event/{id}',
|
||||||
'GET /api/progressionEvents/record/{id}',
|
'GET /api/progressionEvents/record/{id}',
|
||||||
|
'GET /api/purchasableXpBoosts/activations',
|
||||||
'GET /api/quickPlay/v1/getandclear',
|
'GET /api/quickPlay/v1/getandclear',
|
||||||
'GET /api/referee/files',
|
'GET /api/referee/files',
|
||||||
'GET /api/relationships/mutualfriends',
|
'GET /api/relationships/mutualfriends',
|
||||||
|
|||||||
Reference in New Issue
Block a user