Files
mercadodevida/project/src/modules/notifications/api/notifications.routes.ts
2026-08-22 07:09:03 +02:00

76 lines
2.7 KiB
TypeScript

import type { FastifyInstance } from 'fastify';
import type { FastifySchema } from 'fastify';
import type pg from 'pg';
import { z } from 'zod';
import type { Authenticate } from '../../../shared/auth.js';
import { requireRole } from '../../../shared/auth.js';
import { parseJson } from '../../../shared/http-input.js';
import { errorSchema } from '../../../shared/swagger.js';
import { NotificationsService } from '../application/notifications-service.js';
import { PgNotificationsRepository } from '../infrastructure/pg-notifications-repository.js';
export interface NotificationsRoutesDeps {
pool: pg.Pool;
authenticate: Authenticate;
emailProvider: import('../domain/ports.js').EmailProvider;
}
const dispatchSchema = z
.object({
eventId: z.string().min(1).max(120),
template: z.enum(['order_confirmation', 'payment_failed', 'order_shipped', 'account_created']),
recipient: z.string().email(),
subject: z.string().min(1).max(200),
body: z.string().min(1).max(5000),
})
.strip();
export async function registerNotificationsRoutes(
app: FastifyInstance,
deps: NotificationsRoutesDeps,
): Promise<void> {
const service = new NotificationsService(
new PgNotificationsRepository(deps.pool),
deps.emailProvider,
);
const dispatchSwaggerSchema: FastifySchema = {
tags: ['Admin'],
summary: 'Dispatch notification (admin)',
body: { type: 'object' },
response: { 401: errorSchema, 403: errorSchema },
};
app.post('/notifications/dispatch', { schema: dispatchSwaggerSchema }, async (request, reply) => {
const user = await deps.authenticate(request);
requireRole(user, 'admin');
const input = parseJson(dispatchSchema, request.body);
const outcome = await service.dispatch(input);
return reply.send({ outcome });
});
const getMessageSchema: FastifySchema = {
tags: ['Admin'],
summary: 'Get notification message (admin)',
params: { type: 'object', required: ['eventId'], properties: { eventId: { type: 'string' } } },
response: { 401: errorSchema, 403: errorSchema, 404: errorSchema },
};
app.get(
'/notifications/messages/:eventId',
{ schema: getMessageSchema },
async (request, reply) => {
const user = await deps.authenticate(request);
requireRole(user, 'admin');
const params = z.object({ eventId: z.string().min(1).max(120) }).parse(request.params);
const repo = new PgNotificationsRepository(deps.pool);
const found = await repo.findByEventId(params.eventId);
if (!found)
throw new (await import('../../../shared/errors.js')).AppError(
404,
'NOT_FOUND',
'Message not found',
);
return reply.send(found);
},
);
}