mirror of
https://github.com/djdevin/recflare.git
synced 2026-09-08 14:41:28 -07:00
testing generic deploy
This commit is contained in:
+10
-10
@@ -1,6 +1,6 @@
|
||||
# econ
|
||||
|
||||
Economy Worker served at `econ.rec.djdevin.net`. Hosts the avatar/economy
|
||||
Economy Worker served on the `econ` subdomain. Hosts the avatar/economy
|
||||
endpoints the game client calls on the `econ` service (distinct from the main
|
||||
`api` worker). DB-backed data is stubbed for now — no bindings yet.
|
||||
|
||||
@@ -8,21 +8,21 @@ endpoints the game client calls on the `econ` service (distinct from the main
|
||||
|
||||
- `GET /api/avatar/v1/defaultunlocked` — default-unlocked avatar items, served
|
||||
from the bundled `static/default-avatar-items.json` catalog.
|
||||
- `GET /api/avatar/v1/defaultbaseavataritems` — default base avatar items. The C#
|
||||
reads the same source file as `defaultunlocked`, so it returns the identical
|
||||
- `GET /api/avatar/v1/defaultbaseavataritems` — default base avatar items. Reads
|
||||
the same source file as `defaultunlocked`, so it returns the identical
|
||||
catalog.
|
||||
- `GET /api/avatar/v4/items` — `[Authorize]`. The player's avatar items: owned
|
||||
items concatenated with the default catalog. No DB binding yet, so owned is
|
||||
empty and this returns just the catalog.
|
||||
- `GET /api/avatar/v2` — `[Authorize]`. The player's avatar. No DB binding yet,
|
||||
so it returns the default `{ OutfitSelections, FaceFeatures, SkinColor,
|
||||
HairColor }` the C# seeds for a new player.
|
||||
HairColor }` seeded for a new player.
|
||||
- `GET /econ/customAvatarItems/v1/owned` — the player's owned custom avatar
|
||||
items. No auth (matching the C#); returns `{ items: [] }` with no DB binding.
|
||||
items. No auth; returns `{ items: [] }` with no DB binding.
|
||||
The client requests this when custom-item creation is allowed, so a missing
|
||||
route here shows up as "Failed to download unlocked avatar items".
|
||||
- `GET /api/objectives/v1/myprogress` — objectives progress. No auth (matching
|
||||
the C#, which serves a static JSON file verbatim); returns the bundled
|
||||
- `GET /api/objectives/v1/myprogress` — objectives progress. No auth (serves a
|
||||
static JSON file verbatim); returns the bundled
|
||||
`static/my-progress.json` default for all players until a DB binding exists.
|
||||
- `GET /api/avatar/v3/saved` — `[Authorize]`. Saved outfits; `[]` without a DB.
|
||||
- `GET /api/avatar/v2/gifts` — `[Authorize]`. Pending gifts; `[]` without a DB.
|
||||
@@ -33,15 +33,15 @@ HairColor }` the C# seeds for a new player.
|
||||
- `GET /api/storefronts/v3/giftdropstore/3` — gift-drop storefront, served from
|
||||
the bundled `static/storefronts-v3-giftdropstore-3.json`.
|
||||
- `GET /api/challenge/v2/getCurrent` — current weekly challenge, served from the
|
||||
bundled `static/weekly-challenge.json` (the C#'s `JSON/weeklychallenge.json`).
|
||||
bundled `static/weekly-challenge.json`.
|
||||
- `GET /api/gamerewards/v1/pending` — pending rewards; `[]`.
|
||||
- `GET /api/roomkeys/v1/mine` — the player's room keys; `[]`.
|
||||
- `POST /api/CampusCard/v1/UpdateAndGetSubscription` — subscription lookup;
|
||||
`{ subscription: null, platformAccountSubscribedPlayerId: null }`.
|
||||
- Not in CannedNet (stubbed): `GET /api/roomconsumables/v1/roomConsumable/room/:id`
|
||||
- Stubbed: `GET /api/roomconsumables/v1/roomConsumable/room/:id`
|
||||
and `GET /api/roomcurrencies/v1/currencies` both return `[]`.
|
||||
|
||||
These EconController routes are also served by the `api` worker; they're
|
||||
These economy routes are also served by the `api` worker; they're
|
||||
duplicated here because the client calls them on the `econ` host.
|
||||
|
||||
## TODO before production
|
||||
|
||||
+20
-20
@@ -59,8 +59,8 @@ const app = new Hono<App>()
|
||||
// Default-unlocked avatar items, served from the bundled static JSON.
|
||||
.get('/api/avatar/v1/defaultunlocked', (c) => c.json(defaultAvatarItems))
|
||||
|
||||
// Default base avatar items. The C# reads the same JSON/defaultAvatarItems.json
|
||||
// file as defaultunlocked, so it returns the identical catalog.
|
||||
// Default base avatar items. Reads the same source file as defaultunlocked,
|
||||
// so it returns the identical catalog.
|
||||
.get('/api/avatar/v1/defaultbaseavataritems', (c) => c.json(defaultAvatarItems))
|
||||
|
||||
// The player's avatar items — owned items concatenated with the default
|
||||
@@ -72,18 +72,18 @@ const app = new Hono<App>()
|
||||
return c.json(defaultAvatarItems)
|
||||
})
|
||||
|
||||
// The player's owned custom avatar items. No auth in the C#, which returns
|
||||
// `{ items: [] }`. The client downloads these when custom-item creation is
|
||||
// The player's owned custom avatar items. No auth; returns `{ items: [] }`.
|
||||
// The client downloads these when custom-item creation is
|
||||
// allowed; a 404 here surfaces as "Failed to download unlocked avatar items".
|
||||
.get('/econ/customAvatarItems/v1/owned', (c) => c.json({ items: [] }))
|
||||
|
||||
// The player's objectives progress. The C# serves a static JSON file
|
||||
// (JSON/tempmyprogress.json) verbatim with no auth — same default for everyone
|
||||
// until there's a DB binding to track per-player progress.
|
||||
// The player's objectives progress. Serves a static JSON file verbatim with
|
||||
// no auth — same default for everyone until there's a DB binding to track
|
||||
// per-player progress.
|
||||
.get('/api/objectives/v1/myprogress', (c) => c.json(myProgress))
|
||||
|
||||
// The player's avatar. No DB binding yet, so it always returns the default
|
||||
// the C# seeds for a player with no PlayerAvatar row.
|
||||
// for a player with no PlayerAvatar row.
|
||||
.get('/api/avatar/v2', async (c) => {
|
||||
const id = await authedId(c)
|
||||
if (id === null) return unauthorized(c)
|
||||
@@ -117,18 +117,18 @@ const app = new Hono<App>()
|
||||
return c.json([])
|
||||
})
|
||||
|
||||
// Unlocked equipment. The C# returns "[]" with no auth.
|
||||
// Unlocked equipment. Returns "[]" with no auth.
|
||||
.get('/api/equipment/v2/getUnlocked', (c) => c.json([]))
|
||||
|
||||
// Not in CannedNet — room consumables/currencies for a given room. Stubbed
|
||||
// as empty lists so the client doesn't 404.
|
||||
// Room consumables/currencies for a given room. Stubbed as empty lists so the
|
||||
// client doesn't 404.
|
||||
.get('/api/roomconsumables/v1/roomConsumable/room/:roomId', (c) => c.json([]))
|
||||
.get('/api/roomconsumables/v1/roomConsumable/room/:roomId/me', (c) => c.json([]))
|
||||
.get('/api/roomcurrencies/v1/currencies', (c) => c.json([]))
|
||||
.get('/api/roomcurrencies/v1/getAllBalances', (c) => c.json([]))
|
||||
|
||||
// Persist player settings. [Authorize]; the C# replaces the player's settings
|
||||
// and returns Ok(). No DB binding yet, so accept-and-ack.
|
||||
// Persist player settings. [Authorize]; would replace the player's settings.
|
||||
// No DB binding yet, so accept-and-ack.
|
||||
.post('/api/settings/v2/set', async (c) => {
|
||||
const id = await authedId(c)
|
||||
if (id === null) return unauthorized(c)
|
||||
@@ -152,23 +152,23 @@ const app = new Hono<App>()
|
||||
return c.json([])
|
||||
})
|
||||
|
||||
// Gift-drop storefront. The C# falls back to JSON/storefront3.json when no
|
||||
// storefront row exists; that's the bundled static catalog here.
|
||||
// Gift-drop storefront. Falls back to the bundled static catalog when no
|
||||
// storefront row exists.
|
||||
.get('/api/storefronts/v3/giftdropstore/3', (c) => c.json(storefrontGiftDrop3))
|
||||
|
||||
// Current weekly challenge. Served from the bundled static JSON (the C#'s
|
||||
// JSON/weeklychallenge.json) until per-rotation challenge data is wired up.
|
||||
// Current weekly challenge. Served from the bundled static JSON until
|
||||
// per-rotation challenge data is wired up.
|
||||
.get('/api/challenge/v2/getCurrent', (c) => c.json(weeklyChallenge))
|
||||
|
||||
// Pending game rewards. The C# returns "[]".
|
||||
// Pending game rewards. Returns "[]".
|
||||
.get('/api/gamerewards/v1/pending', (c) => c.json([]))
|
||||
|
||||
// The player's room keys. The C# returns "[]".
|
||||
// The player's room keys. Returns "[]".
|
||||
.get('/api/roomkeys/v1/mine', (c) => c.json([]))
|
||||
// Room keys for a given room (client calls this on the econ host). [] with no DB.
|
||||
.get('/api/roomkeys/v1/room', (c) => c.json([]))
|
||||
|
||||
// Subscription lookup. The C# returns both fields null with no auth.
|
||||
// Subscription lookup. Returns both fields null with no auth.
|
||||
.post('/api/CampusCard/v1/UpdateAndGetSubscription', (c) =>
|
||||
c.json({ subscription: null, platformAccountSubscribedPlayerId: null })
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Minimal HS256 JWT validation, mirroring the C# `JwtTokenService.ValidateAndGetAccountId`.
|
||||
* Minimal HS256 JWT validation.
|
||||
*
|
||||
* Uses the same placeholder dev secret as the `auth` worker (`apps/auth/src/jwt.ts`).
|
||||
* Swap both for a shared secret binding before this is used for anything real.
|
||||
|
||||
@@ -3,7 +3,7 @@ import { describe, expect, test } from 'vitest'
|
||||
|
||||
import '../../econ.app'
|
||||
|
||||
const ORIGIN = 'https://econ.rec.djdevin.net'
|
||||
const ORIGIN = 'https://example.com'
|
||||
|
||||
// Mint a token the way the `auth` worker does, using the same dev secret.
|
||||
const DEV_SECRET = 'dev-insecure-signing-key-change-me'
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"compatibility_flags": ["nodejs_compat"],
|
||||
"routes": [
|
||||
{
|
||||
"pattern": "econ.rec.djdevin.net",
|
||||
"pattern": "econ.rec.example.com",
|
||||
"custom_domain": true
|
||||
}
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user