feat(F-177): completed feature
This commit is contained in:
@@ -180,6 +180,59 @@ export async function registerOrdersRoutes(
|
||||
return reply.send({ items: items.map(serializeOrder), total });
|
||||
});
|
||||
|
||||
const staleNotificationsSchema: FastifySchema = {
|
||||
tags: ['Orders'],
|
||||
summary: 'List stale order notifications (admin)',
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
hours: { type: 'integer', minimum: 1, maximum: 168, default: 24 },
|
||||
limit: { type: 'integer', minimum: 1, maximum: 50, default: 20 },
|
||||
},
|
||||
},
|
||||
response: { 401: errorSchema, 403: errorSchema },
|
||||
};
|
||||
app.get('/orders/notifications/stale', { schema: staleNotificationsSchema }, async (request, reply) => {
|
||||
const user = await deps.authenticate(request);
|
||||
requireRole(user, 'admin');
|
||||
const query = request.query as { hours?: string; limit?: string };
|
||||
const hours = Math.min(Math.max(Number(query.hours ?? 24) || 24, 1), 168);
|
||||
const limit = Math.min(Math.max(Number(query.limit ?? 20) || 20, 1), 50);
|
||||
const result = await deps.pool.query<{
|
||||
id: string;
|
||||
state: 'PENDING' | 'SHIPPED';
|
||||
total_cents: number;
|
||||
customer_email: string | null;
|
||||
state_changed_at: Date;
|
||||
age_hours: number;
|
||||
total_count: number;
|
||||
}>(
|
||||
`SELECT o.id, o.state, o.total_cents, u.email AS customer_email,
|
||||
o.state_changed_at,
|
||||
FLOOR(EXTRACT(EPOCH FROM (now() - o.state_changed_at)) / 3600)::int AS age_hours,
|
||||
COUNT(*) OVER()::int AS total_count
|
||||
FROM orders_orders o
|
||||
LEFT JOIN identity_users u ON u.id = o.user_id
|
||||
WHERE o.state IN ('PENDING', 'SHIPPED')
|
||||
AND o.state_changed_at <= now() - ($1::int * interval '1 hour')
|
||||
ORDER BY o.state_changed_at ASC
|
||||
LIMIT $2`,
|
||||
[hours, limit],
|
||||
);
|
||||
return reply.send({
|
||||
total: result.rows[0]?.total_count ?? 0,
|
||||
thresholdHours: hours,
|
||||
items: result.rows.map((row) => ({
|
||||
id: row.id,
|
||||
state: row.state,
|
||||
totalCents: row.total_cents,
|
||||
customerEmail: row.customer_email,
|
||||
stateChangedAt: row.state_changed_at.toISOString(),
|
||||
ageHours: row.age_hours,
|
||||
})),
|
||||
});
|
||||
});
|
||||
|
||||
const getOrderAdminSchema: FastifySchema = {
|
||||
tags: ['Orders'],
|
||||
summary: 'Get order (admin)',
|
||||
|
||||
Reference in New Issue
Block a user