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, users, tickets, payments, events, invoices, User } from '../db/index.js';
|
||||
import { db, dbGet, dbAll, users, tickets, payments, events, invoices, User } from '../db/index.js';
|
||||
import { eq, desc, and, gt, sql } from 'drizzle-orm';
|
||||
import { requireAuth, getUserSessions, invalidateSession, invalidateAllUserSessions, hashPassword, validatePassword } from '../lib/auth.js';
|
||||
import { generateId, getNow } from '../lib/utils.js';
|
||||
@@ -70,11 +70,12 @@ dashboard.put('/profile', zValidator('json', updateProfileSchema), async (c) =>
|
||||
})
|
||||
.where(eq((users as any).id, user.id));
|
||||
|
||||
const updatedUser = await (db as any)
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq((users as any).id, user.id))
|
||||
.get();
|
||||
const updatedUser = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq((users as any).id, user.id))
|
||||
);
|
||||
|
||||
return c.json({
|
||||
profile: {
|
||||
@@ -95,36 +96,40 @@ dashboard.put('/profile', zValidator('json', updateProfileSchema), async (c) =>
|
||||
dashboard.get('/tickets', async (c) => {
|
||||
const user = (c as any).get('user') as AuthUser;
|
||||
|
||||
const userTickets = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
.orderBy(desc((tickets as any).createdAt))
|
||||
.all();
|
||||
const userTickets = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
.orderBy(desc((tickets as any).createdAt))
|
||||
);
|
||||
|
||||
// Get event details for each ticket
|
||||
const ticketsWithEvents = await Promise.all(
|
||||
userTickets.map(async (ticket: any) => {
|
||||
const event = await (db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
const event = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticket.id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticket.id))
|
||||
);
|
||||
|
||||
// Check for invoice
|
||||
let invoice = null;
|
||||
let invoice: any = null;
|
||||
if (payment && payment.status === 'paid') {
|
||||
invoice = await (db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).paymentId, payment.id))
|
||||
.get();
|
||||
invoice = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).paymentId, payment.id))
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -168,40 +173,44 @@ dashboard.get('/tickets/:id', async (c) => {
|
||||
const user = (c as any).get('user') as AuthUser;
|
||||
const ticketId = c.req.param('id');
|
||||
|
||||
const ticket = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(
|
||||
and(
|
||||
eq((tickets as any).id, ticketId),
|
||||
eq((tickets as any).userId, user.id)
|
||||
const ticket = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(
|
||||
and(
|
||||
eq((tickets as any).id, ticketId),
|
||||
eq((tickets as any).userId, user.id)
|
||||
)
|
||||
)
|
||||
)
|
||||
.get();
|
||||
);
|
||||
|
||||
if (!ticket) {
|
||||
return c.json({ error: 'Ticket not found' }, 404);
|
||||
}
|
||||
|
||||
const event = await (db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
const event = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticket.id))
|
||||
.get();
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticket.id))
|
||||
);
|
||||
|
||||
let invoice = null;
|
||||
if (payment && payment.status === 'paid') {
|
||||
invoice = await (db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).paymentId, payment.id))
|
||||
.get();
|
||||
invoice = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).paymentId, payment.id))
|
||||
);
|
||||
}
|
||||
|
||||
return c.json({
|
||||
@@ -222,11 +231,12 @@ dashboard.get('/next-event', async (c) => {
|
||||
const now = getNow();
|
||||
|
||||
// Get user's tickets for upcoming events
|
||||
const userTickets = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
.all();
|
||||
const userTickets = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
);
|
||||
|
||||
if (userTickets.length === 0) {
|
||||
return c.json({ nextEvent: null });
|
||||
@@ -240,11 +250,12 @@ dashboard.get('/next-event', async (c) => {
|
||||
for (const ticket of userTickets) {
|
||||
if (ticket.status === 'cancelled') continue;
|
||||
|
||||
const event = await (db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
const event = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
|
||||
if (!event) continue;
|
||||
|
||||
@@ -253,11 +264,12 @@ dashboard.get('/next-event', async (c) => {
|
||||
if (!nextEvent || new Date(event.startDatetime) < new Date(nextEvent.startDatetime)) {
|
||||
nextEvent = event;
|
||||
nextTicket = ticket;
|
||||
nextPayment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticket.id))
|
||||
.get();
|
||||
nextPayment = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticket.id))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -282,11 +294,12 @@ dashboard.get('/payments', async (c) => {
|
||||
const user = (c as any).get('user') as AuthUser;
|
||||
|
||||
// Get all user's tickets first
|
||||
const userTickets = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
.all();
|
||||
const userTickets = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
);
|
||||
|
||||
const ticketIds = userTickets.map((t: any) => t.id);
|
||||
|
||||
@@ -297,29 +310,32 @@ dashboard.get('/payments', async (c) => {
|
||||
// Get all payments for user's tickets
|
||||
const allPayments = [];
|
||||
for (const ticketId of ticketIds) {
|
||||
const ticketPayments = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticketId))
|
||||
.all();
|
||||
const ticketPayments = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).ticketId, ticketId))
|
||||
);
|
||||
|
||||
for (const payment of ticketPayments) {
|
||||
const ticket = userTickets.find((t: any) => t.id === payment.ticketId);
|
||||
const event = ticket
|
||||
? await (db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get()
|
||||
? await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
)
|
||||
: null;
|
||||
|
||||
let invoice = null;
|
||||
let invoice: any = null;
|
||||
if (payment.status === 'paid') {
|
||||
invoice = await (db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).paymentId, payment.id))
|
||||
.get();
|
||||
invoice = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).paymentId, payment.id))
|
||||
);
|
||||
}
|
||||
|
||||
allPayments.push({
|
||||
@@ -355,36 +371,40 @@ dashboard.get('/payments', async (c) => {
|
||||
dashboard.get('/invoices', async (c) => {
|
||||
const user = (c as any).get('user') as AuthUser;
|
||||
|
||||
const userInvoices = await (db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).userId, user.id))
|
||||
.orderBy(desc((invoices as any).createdAt))
|
||||
.all();
|
||||
const userInvoices = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(invoices)
|
||||
.where(eq((invoices as any).userId, user.id))
|
||||
.orderBy(desc((invoices as any).createdAt))
|
||||
);
|
||||
|
||||
// Get payment and event details for each invoice
|
||||
const invoicesWithDetails = await Promise.all(
|
||||
userInvoices.map(async (invoice: any) => {
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, invoice.paymentId))
|
||||
.get();
|
||||
|
||||
let event = null;
|
||||
if (payment) {
|
||||
const ticket = await (db as any)
|
||||
const payment = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
.get();
|
||||
.from(payments)
|
||||
.where(eq((payments as any).id, invoice.paymentId))
|
||||
);
|
||||
|
||||
let event: any = null;
|
||||
if (payment) {
|
||||
const ticket = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).id, payment.ticketId))
|
||||
);
|
||||
|
||||
if (ticket) {
|
||||
event = await (db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
event = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,11 +531,12 @@ dashboard.get('/summary', async (c) => {
|
||||
const membershipDays = Math.floor((now.getTime() - createdDate.getTime()) / (1000 * 60 * 60 * 24));
|
||||
|
||||
// Get ticket count
|
||||
const userTickets = await (db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
.all();
|
||||
const userTickets = await dbAll<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(tickets)
|
||||
.where(eq((tickets as any).userId, user.id))
|
||||
);
|
||||
|
||||
const totalTickets = userTickets.length;
|
||||
const confirmedTickets = userTickets.filter((t: any) => t.status === 'confirmed' || t.status === 'checked_in').length;
|
||||
@@ -524,11 +545,12 @@ dashboard.get('/summary', async (c) => {
|
||||
for (const ticket of userTickets) {
|
||||
if (ticket.status === 'cancelled') continue;
|
||||
|
||||
const event = await (db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
.get();
|
||||
const event = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(events)
|
||||
.where(eq((events as any).id, ticket.eventId))
|
||||
);
|
||||
|
||||
if (event && new Date(event.startDatetime) > now) {
|
||||
upcomingTickets.push({ ticket, event });
|
||||
@@ -540,16 +562,17 @@ dashboard.get('/summary', async (c) => {
|
||||
let pendingPayments = 0;
|
||||
|
||||
for (const ticketId of ticketIds) {
|
||||
const payment = await (db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(
|
||||
and(
|
||||
eq((payments as any).ticketId, ticketId),
|
||||
eq((payments as any).status, 'pending_approval')
|
||||
const payment = await dbGet(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(payments)
|
||||
.where(
|
||||
and(
|
||||
eq((payments as any).ticketId, ticketId),
|
||||
eq((payments as any).status, 'pending_approval')
|
||||
)
|
||||
)
|
||||
)
|
||||
.get();
|
||||
);
|
||||
|
||||
if (payment) pendingPayments++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user