|
|
|
|
@@ -1,9 +1,11 @@
|
|
|
|
|
import type { FastifyInstance } from 'fastify';
|
|
|
|
|
import type { FastifySchema } from 'fastify';
|
|
|
|
|
import type pg from 'pg';
|
|
|
|
|
import { z } from 'zod';
|
|
|
|
|
import { requireRole, type Authenticate } from '../../../shared/auth.js';
|
|
|
|
|
import { parseJson } from '../../../shared/http-input.js';
|
|
|
|
|
import { AppError } from '../../../shared/errors.js';
|
|
|
|
|
import { errorSchema } from '../../../shared/swagger.js';
|
|
|
|
|
import { PromotionServiceImpl } from '../application/promotion-service.js';
|
|
|
|
|
import type { Promotion } from '../domain/promotion.js';
|
|
|
|
|
import { PgPromotionRepository } from '../infrastructure/pg-promotion-repository.js';
|
|
|
|
|
@@ -32,7 +34,12 @@ export async function registerPromotionsRoutes(
|
|
|
|
|
const service = new PromotionServiceImpl(new PgPromotionRepository(deps.pool));
|
|
|
|
|
|
|
|
|
|
// List all promotions (admin)
|
|
|
|
|
app.get('/promotions', async (request, reply) => {
|
|
|
|
|
const listPromoSchema: FastifySchema = {
|
|
|
|
|
tags: ['Promotions'],
|
|
|
|
|
summary: 'List promotions (admin)',
|
|
|
|
|
response: { 401: errorSchema, 403: errorSchema },
|
|
|
|
|
};
|
|
|
|
|
app.get('/promotions', { schema: listPromoSchema }, async (request, reply) => {
|
|
|
|
|
const user = await deps.authenticate(request);
|
|
|
|
|
requireRole(user, 'admin');
|
|
|
|
|
const items = await service.list();
|
|
|
|
|
@@ -40,7 +47,13 @@ export async function registerPromotionsRoutes(
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Create promotion (admin)
|
|
|
|
|
app.post('/promotions', async (request, reply) => {
|
|
|
|
|
const createPromoSchema: FastifySchema = {
|
|
|
|
|
tags: ['Promotions'],
|
|
|
|
|
summary: 'Create promotion (admin)',
|
|
|
|
|
body: { type: 'object' },
|
|
|
|
|
response: { 201: { type: 'object' }, 401: errorSchema, 403: errorSchema },
|
|
|
|
|
};
|
|
|
|
|
app.post('/promotions', { schema: createPromoSchema }, async (request, reply) => {
|
|
|
|
|
const user = await deps.authenticate(request);
|
|
|
|
|
requireRole(user, 'admin');
|
|
|
|
|
const input = parseJson(promotionBodySchema, request.body);
|
|
|
|
|
@@ -49,7 +62,14 @@ export async function registerPromotionsRoutes(
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Update promotion (admin)
|
|
|
|
|
app.patch('/promotions/:code', async (request, reply) => {
|
|
|
|
|
const patchPromoSchema: FastifySchema = {
|
|
|
|
|
tags: ['Promotions'],
|
|
|
|
|
summary: 'Update promotion (admin)',
|
|
|
|
|
params: { type: 'object', required: ['code'], properties: { code: { type: 'string' } } },
|
|
|
|
|
body: { type: 'object' },
|
|
|
|
|
response: { 401: errorSchema, 403: errorSchema, 404: errorSchema },
|
|
|
|
|
};
|
|
|
|
|
app.patch('/promotions/:code', { schema: patchPromoSchema }, async (request, reply) => {
|
|
|
|
|
const user = await deps.authenticate(request);
|
|
|
|
|
requireRole(user, 'admin');
|
|
|
|
|
const { code } = parseJson(z.object({ code: z.string() }), request.params);
|
|
|
|
|
@@ -60,12 +80,20 @@ export async function registerPromotionsRoutes(
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error instanceof Error && error.message === 'Promotion not found'
|
|
|
|
|
? new AppError(404, 'NOT_FOUND', 'Promotion not found')
|
|
|
|
|
: (error instanceof Error ? error : new Error('Unknown error'));
|
|
|
|
|
: error instanceof Error
|
|
|
|
|
? error
|
|
|
|
|
: new Error('Unknown error');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Delete promotion (admin)
|
|
|
|
|
app.delete('/promotions/:code', async (request, reply) => {
|
|
|
|
|
const deletePromoSchema: FastifySchema = {
|
|
|
|
|
tags: ['Promotions'],
|
|
|
|
|
summary: 'Delete promotion (admin)',
|
|
|
|
|
params: { type: 'object', required: ['code'], properties: { code: { type: 'string' } } },
|
|
|
|
|
response: { 204: { type: 'null' }, 401: errorSchema, 403: errorSchema, 404: errorSchema },
|
|
|
|
|
};
|
|
|
|
|
app.delete('/promotions/:code', { schema: deletePromoSchema }, async (request, reply) => {
|
|
|
|
|
const user = await deps.authenticate(request);
|
|
|
|
|
requireRole(user, 'admin');
|
|
|
|
|
const { code } = parseJson(z.object({ code: z.string() }), request.params);
|
|
|
|
|
|