diff --git a/apps/econ/src/econ.app.ts b/apps/econ/src/econ.app.ts index 99a6b77..294d0b2 100644 --- a/apps/econ/src/econ.app.ts +++ b/apps/econ/src/econ.app.ts @@ -326,6 +326,11 @@ const app = new Hono({ strict: false }) // per-player progress. .get('/api/objectives/v1/myprogress', (c) => c.json(myProgress)) + // Clears a group of objectives. No per-player progress to clear yet, so this + // is a no-op that returns an empty array (a 404 here breaks the client). Accepts + // GET or POST since the client may use either. + .on(['GET', 'POST'], '/api/objectives/v1/cleargroup', (c) => c.json([])) + // The player's avatar, stored as a JSON blob on their account row. Falls back // to the default outfit when they haven't saved one — the client's parser NREs // on an empty OutfitSelections (real RecNet never returns one). diff --git a/apps/econ/src/test/integration/api.test.ts b/apps/econ/src/test/integration/api.test.ts index c06e8e4..6b37060 100644 --- a/apps/econ/src/test/integration/api.test.ts +++ b/apps/econ/src/test/integration/api.test.ts @@ -260,6 +260,14 @@ describe('econ endpoints', () => { expect(Array.isArray(body.ObjectiveGroups)).toBe(true) }) + test('objectives/v1/cleargroup returns [] for GET and POST (no auth)', async () => { + for (const method of ['GET', 'POST'] as const) { + const res = await exports.default.fetch(`${ORIGIN}/api/objectives/v1/cleargroup`, { method }) + expect(res.status).toBe(200) + expect(await res.json()).toEqual([]) + } + }) + test('GET /api/checklist/v1/current 401s without a token, returns [] with one', async () => { const anon = await exports.default.fetch(`${ORIGIN}/api/checklist/v1/current`) expect(anon.status).toBe(401)