41 lines
1.4 KiB
TypeScript
Executable File
41 lines
1.4 KiB
TypeScript
Executable File
import { Router, Request, Response } from 'express';
|
|
import { pool } from '../db';
|
|
|
|
const router = Router();
|
|
|
|
router.get('/', async (_req: Request, res: Response) => {
|
|
const { rows } = await pool.query(`
|
|
SELECT
|
|
c.id, c.email, c.name, c.email_verified, c.marketing_consent, c.created_at,
|
|
COUNT(o.id) FILTER (WHERE o.status = 'completed') AS order_count,
|
|
COALESCE(SUM(o.amount_cents) FILTER (WHERE o.status = 'completed'), 0) AS total_spent_cents,
|
|
MAX(o.created_at) AS last_order_at
|
|
FROM customers c
|
|
LEFT JOIN orders o ON o.customer_id = c.id
|
|
GROUP BY c.id
|
|
ORDER BY c.created_at DESC
|
|
`);
|
|
res.json(rows);
|
|
});
|
|
|
|
router.get('/:id', async (req: Request, res: Response) => {
|
|
const { rows: customerRows } = await pool.query(
|
|
`SELECT id, email, name, email_verified, marketing_consent, marketing_consent_at, created_at
|
|
FROM customers WHERE id = $1`,
|
|
[req.params.id]
|
|
);
|
|
if (!customerRows.length) return res.status(404).json({ error: 'not found' });
|
|
|
|
const { rows: orderRows } = await pool.query(
|
|
`SELECT o.id, o.processor, o.processor_order_id, o.amount_cents, o.status, o.created_at, i.name AS item_name
|
|
FROM orders o JOIN items i ON i.id = o.item_id
|
|
WHERE o.customer_id = $1
|
|
ORDER BY o.created_at DESC`,
|
|
[req.params.id]
|
|
);
|
|
|
|
res.json({ customer: customerRows[0], orders: orderRows });
|
|
});
|
|
|
|
export default router;
|