server: game API modules — market, missions, players, inventory, leaderboard, cities, events
Add routes and services for all game domains: market buy/sell with dynamic pricing, mission generation and completion, player stats and travel, inventory queries, leaderboard, city list, and world events. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import type { FastifyPluginAsync } from 'fastify';
|
||||
import { z } from 'zod';
|
||||
import { emitToPlayer } from '../../realtime/socket.js';
|
||||
import { authGuard } from '../../shared/authGuard.js';
|
||||
import { parseOrThrow } from '../../shared/validators.js';
|
||||
import { claimMission, listActive, listAvailable, startMission } from './missions.service.js';
|
||||
|
||||
const missionParamsSchema = z.object({ missionId: z.string().uuid() });
|
||||
const playerMissionParamsSchema = z.object({ playerMissionId: z.string().uuid() });
|
||||
|
||||
export const missionsRoutes: FastifyPluginAsync = async (app) => {
|
||||
app.addHook('preHandler', authGuard);
|
||||
|
||||
app.get('/available', async (request) => {
|
||||
return listAvailable(request.user.playerId);
|
||||
});
|
||||
|
||||
app.get('/active', async (request) => {
|
||||
return listActive(request.user.playerId);
|
||||
});
|
||||
|
||||
app.post('/:missionId/start', async (request, reply) => {
|
||||
const { missionId } = parseOrThrow(missionParamsSchema, request.params);
|
||||
const playerMission = await startMission(request.user.playerId, missionId);
|
||||
request.log.info(
|
||||
{ playerId: request.user.playerId, missionId, playerMissionId: playerMission.id },
|
||||
'mission:start',
|
||||
);
|
||||
return reply.status(201).send({
|
||||
playerMissionId: playerMission.id,
|
||||
status: playerMission.status,
|
||||
startedAt: playerMission.startedAt,
|
||||
completesAt: playerMission.completesAt,
|
||||
});
|
||||
});
|
||||
|
||||
app.post('/:playerMissionId/claim', async (request) => {
|
||||
const { playerMissionId } = parseOrThrow(playerMissionParamsSchema, request.params);
|
||||
const result = await claimMission(request.user.playerId, playerMissionId);
|
||||
request.log.info(
|
||||
{
|
||||
playerId: request.user.playerId,
|
||||
playerMissionId,
|
||||
success: result.success,
|
||||
rewardMoney: result.rewardMoney,
|
||||
},
|
||||
'mission:claim',
|
||||
);
|
||||
emitToPlayer(request.user.playerId, 'player:notification', {
|
||||
type: 'mission:result',
|
||||
playerMissionId,
|
||||
success: result.success,
|
||||
});
|
||||
return result;
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user