Add PostgreSQL support with SQLite/Postgres database compatibility layer
- Add dbGet/dbAll helper functions for database-agnostic queries - Add toDbBool/convertBooleansForDb for boolean type conversion - Add toDbDate/getNow for timestamp type handling - Add generateId that returns UUID for Postgres, nanoid for SQLite - Update all routes to use compatibility helpers - Add normalizeEvent to return clean number types from Postgres decimal - Add formatPrice utility for consistent price display - Add legal pages admin interface with RichTextEditor - Update carousel images - Add drizzle migration files for PostgreSQL
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Hono } from 'hono';
|
||||
import { zValidator } from '@hono/zod-validator';
|
||||
import { z } from 'zod';
|
||||
import { db, payments, tickets, events } from '../db/index.js';
|
||||
import { db, dbGet, dbAll, payments, tickets, events } from '../db/index.js';
|
||||
import { eq, desc, and, or, sql } from 'drizzle-orm';
|
||||
import { requireAuth } from '../lib/auth.js';
|
||||
import { getNow } from '../lib/utils.js';
|
||||
@@ -30,11 +30,12 @@ paymentsRouter.get('/', requireAuth(['admin']), async (c) => {
|
||||
const pendingApproval = c.req.query('pendingApproval');
|
||||
|
||||
// Get all payments with their associated tickets
|
||||
let allPayments = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.orderBy(desc((payments as any).createdAt))
|
||||
.all();
|
||||
let allPayments = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.orderBy(desc((payments as any).createdAt))
|
||||
);
|
||||
|
||||
// Filter by status
|
||||
if (status) {
|
||||
@@ -54,19 +55,21 @@ paymentsRouter.get('/', requireAuth(['admin']), async (c) => {
|
||||
// Enrich with ticket and event data
|
||||
const enrichedPayments = await Promise.all(
|
||||
allPayments.map(async (payment: any) => {
|
||||
const ticket = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
.get();
|
||||
|
||||
let event = null;
|
||||
if (ticket) {
|
||||
event = await (db as any)
|
||||
const ticket = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
);
|
||||
|
||||
let event: any = null;
|
||||
if (ticket) {
|
||||
event = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -93,29 +96,32 @@ paymentsRouter.get('/', requireAuth(['admin']), async (c) => {
|
||||
|
||||
// Get payments pending approval (admin dashboard view)
|
||||
paymentsRouter.get('/pending-approval', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
const pendingPayments = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).status, 'pending_approval'))
|
||||
.orderBy(desc((payments as any).userMarkedPaidAt))
|
||||
.all();
|
||||
const pendingPayments = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).status, 'pending_approval'))
|
||||
.orderBy(desc((payments as any).userMarkedPaidAt))
|
||||
);
|
||||
|
||||
// Enrich with ticket and event data
|
||||
const enrichedPayments = await Promise.all(
|
||||
pendingPayments.map(async (payment: any) => {
|
||||
const ticket = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
.get();
|
||||
|
||||
let event = null;
|
||||
if (ticket) {
|
||||
event = await (db as any)
|
||||
const ticket = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
);
|
||||
|
||||
let event: any = null;
|
||||
if (ticket) {
|
||||
event = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -144,22 +150,24 @@ paymentsRouter.get('/pending-approval', requireAuth(['admin', 'organizer']), asy
|
||||
paymentsRouter.get('/:id', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
const id = c.req.param('id');
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
if (!payment) {
|
||||
return c.json({ error: 'Payment not found' }, 404);
|
||||
}
|
||||
|
||||
// Get associated ticket
|
||||
const ticket = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
.get();
|
||||
const ticket = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
);
|
||||
|
||||
return c.json({ payment: { ...payment, ticket } });
|
||||
});
|
||||
@@ -170,11 +178,12 @@ paymentsRouter.put('/:id', requireAuth(['admin', 'organizer']), zValidator('json
|
||||
const data = c.req.valid('json');
|
||||
const user = (c as any).get('user');
|
||||
|
||||
const existing = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const existing = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
if (!existing) {
|
||||
return c.json({ error: 'Payment not found' }, 404);
|
||||
@@ -211,11 +220,12 @@ paymentsRouter.put('/:id', requireAuth(['admin', 'organizer']), zValidator('json
|
||||
});
|
||||
}
|
||||
|
||||
const updated = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const updated = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
return c.json({ payment: updated });
|
||||
});
|
||||
@@ -226,11 +236,12 @@ paymentsRouter.post('/:id/approve', requireAuth(['admin', 'organizer']), zValida
|
||||
const { adminNote } = c.req.valid('json');
|
||||
const user = (c as any).get('user');
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
if (!payment) {
|
||||
return c.json({ error: 'Payment not found' }, 404);
|
||||
@@ -269,11 +280,12 @@ paymentsRouter.post('/:id/approve', requireAuth(['admin', 'organizer']), zValida
|
||||
console.error('[Email] Failed to send confirmation emails:', err);
|
||||
});
|
||||
|
||||
const updated = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const updated = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
return c.json({ payment: updated, message: 'Payment approved successfully' });
|
||||
});
|
||||
@@ -284,11 +296,12 @@ paymentsRouter.post('/:id/reject', requireAuth(['admin', 'organizer']), zValidat
|
||||
const { adminNote } = c.req.valid('json');
|
||||
const user = (c as any).get('user');
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
if (!payment) {
|
||||
return c.json({ error: 'Payment not found' }, 404);
|
||||
@@ -327,11 +340,12 @@ paymentsRouter.post('/:id/reject', requireAuth(['admin', 'organizer']), zValidat
|
||||
});
|
||||
}
|
||||
|
||||
const updated = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const updated = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
return c.json({ payment: updated, message: 'Payment rejected and booking cancelled' });
|
||||
});
|
||||
@@ -342,11 +356,12 @@ paymentsRouter.post('/:id/note', requireAuth(['admin', 'organizer']), async (c)
|
||||
const body = await c.req.json();
|
||||
const { adminNote } = body;
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
if (!payment) {
|
||||
return c.json({ error: 'Payment not found' }, 404);
|
||||
@@ -362,11 +377,12 @@ paymentsRouter.post('/:id/note', requireAuth(['admin', 'organizer']), async (c)
|
||||
})
|
||||
.where(eq((payments as any).id, id));
|
||||
|
||||
const updated = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const updated = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
return c.json({ payment: updated, message: 'Note updated' });
|
||||
});
|
||||
@@ -375,11 +391,12 @@ paymentsRouter.post('/:id/note', requireAuth(['admin', 'organizer']), async (c)
|
||||
paymentsRouter.post('/:id/refund', requireAuth(['admin']), async (c) => {
|
||||
const id = c.req.param('id');
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, id))
|
||||
);
|
||||
|
||||
if (!payment) {
|
||||
return c.json({ error: 'Payment not found' }, 404);
|
||||
@@ -426,7 +443,7 @@ paymentsRouter.post('/webhook', async (c) => {
|
||||
|
||||
// Get payment statistics (admin)
|
||||
paymentsRouter.get('/stats/overview', requireAuth(['admin']), async (c) => {
|
||||
const allPayments = await (db as any).select().from(payments).all();
|
||||
const allPayments = await dbAll<any>((db as any).select().from(payments));
|
||||
|
||||
const stats = {
|
||||
total: allPayments.length,
|
||||
|
||||
Reference in New Issue
Block a user