feat(F-177): completed feature

This commit is contained in:
chattie
2026-08-22 18:54:41 +02:00
parent 4081462cc4
commit abdb03b6b5
17 changed files with 326 additions and 23 deletions

View File

@@ -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)',