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,9 +1,8 @@
|
||||
import { Hono } from 'hono';
|
||||
import { db, emailTemplates, emailLogs, events, tickets } from '../db/index.js';
|
||||
import { db, dbGet, dbAll, emailTemplates, emailLogs, events, tickets } from '../db/index.js';
|
||||
import { eq, desc, and, sql } from 'drizzle-orm';
|
||||
import { requireAuth } from '../lib/auth.js';
|
||||
import { getNow } from '../lib/utils.js';
|
||||
import { nanoid } from 'nanoid';
|
||||
import { getNow, generateId } from '../lib/utils.js';
|
||||
import emailService from '../lib/email.js';
|
||||
import { getTemplateVariables, defaultTemplates } from '../lib/emailTemplates.js';
|
||||
|
||||
@@ -13,11 +12,9 @@ const emailsRouter = new Hono();
|
||||
|
||||
// Get all email templates
|
||||
emailsRouter.get('/templates', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
const templates = await (db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.orderBy(desc((emailTemplates as any).createdAt))
|
||||
.all();
|
||||
const templates = await dbAll<any>(
|
||||
(db as any).select().from(emailTemplates).orderBy(desc((emailTemplates as any).createdAt))
|
||||
);
|
||||
|
||||
// Parse variables JSON for each template
|
||||
const parsedTemplates = templates.map((t: any) => ({
|
||||
@@ -34,11 +31,12 @@ emailsRouter.get('/templates', requireAuth(['admin', 'organizer']), async (c) =>
|
||||
emailsRouter.get('/templates/:id', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
const { id } = c.req.param();
|
||||
|
||||
const template = await (db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
.get();
|
||||
const template = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
);
|
||||
|
||||
if (!template) {
|
||||
return c.json({ error: 'Template not found' }, 404);
|
||||
@@ -64,11 +62,9 @@ emailsRouter.post('/templates', requireAuth(['admin']), async (c) => {
|
||||
}
|
||||
|
||||
// Check if slug already exists
|
||||
const existing = await (db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).slug, slug))
|
||||
.get();
|
||||
const existing = await dbGet<any>(
|
||||
(db as any).select().from(emailTemplates).where(eq((emailTemplates as any).slug, slug))
|
||||
);
|
||||
|
||||
if (existing) {
|
||||
return c.json({ error: 'Template with this slug already exists' }, 400);
|
||||
@@ -76,7 +72,7 @@ emailsRouter.post('/templates', requireAuth(['admin']), async (c) => {
|
||||
|
||||
const now = getNow();
|
||||
const template = {
|
||||
id: nanoid(),
|
||||
id: generateId(),
|
||||
name,
|
||||
slug,
|
||||
subject,
|
||||
@@ -111,11 +107,12 @@ emailsRouter.put('/templates/:id', requireAuth(['admin']), async (c) => {
|
||||
const { id } = c.req.param();
|
||||
const body = await c.req.json();
|
||||
|
||||
const existing = await (db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
.get();
|
||||
const existing = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
);
|
||||
|
||||
if (!existing) {
|
||||
return c.json({ error: 'Template not found' }, 404);
|
||||
@@ -148,11 +145,12 @@ emailsRouter.put('/templates/:id', requireAuth(['admin']), async (c) => {
|
||||
.set(updateData)
|
||||
.where(eq((emailTemplates as any).id, id));
|
||||
|
||||
const updated = await (db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
.get();
|
||||
const updated = await dbGet<any>(
|
||||
(db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
);
|
||||
|
||||
return c.json({
|
||||
template: {
|
||||
@@ -169,11 +167,9 @@ emailsRouter.put('/templates/:id', requireAuth(['admin']), async (c) => {
|
||||
emailsRouter.delete('/templates/:id', requireAuth(['admin']), async (c) => {
|
||||
const { id } = c.req.param();
|
||||
|
||||
const template = await (db as any)
|
||||
.select()
|
||||
.from(emailTemplates)
|
||||
.where(eq((emailTemplates as any).id, id))
|
||||
.get();
|
||||
const template = await dbGet<any>(
|
||||
(db as any).select().from(emailTemplates).where(eq((emailTemplates as any).id, id))
|
||||
);
|
||||
|
||||
if (!template) {
|
||||
return c.json({ error: 'Template not found' }, 404);
|
||||
@@ -306,11 +302,12 @@ emailsRouter.get('/logs', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
query = query.where(and(...conditions));
|
||||
}
|
||||
|
||||
const logs = await query
|
||||
.orderBy(desc((emailLogs as any).createdAt))
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
.all();
|
||||
const logs = await dbAll(
|
||||
query
|
||||
.orderBy(desc((emailLogs as any).createdAt))
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
);
|
||||
|
||||
// Get total count
|
||||
let countQuery = (db as any)
|
||||
@@ -321,7 +318,7 @@ emailsRouter.get('/logs', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
countQuery = countQuery.where(and(...conditions));
|
||||
}
|
||||
|
||||
const totalResult = await countQuery.get();
|
||||
const totalResult = await dbGet<any>(countQuery);
|
||||
const total = totalResult?.count || 0;
|
||||
|
||||
return c.json({
|
||||
@@ -339,11 +336,9 @@ emailsRouter.get('/logs', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
emailsRouter.get('/logs/:id', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
const { id } = c.req.param();
|
||||
|
||||
const log = await (db as any)
|
||||
.select()
|
||||
.from(emailLogs)
|
||||
.where(eq((emailLogs as any).id, id))
|
||||
.get();
|
||||
const log = await dbGet<any>(
|
||||
(db as any).select().from(emailLogs).where(eq((emailLogs as any).id, id))
|
||||
);
|
||||
|
||||
if (!log) {
|
||||
return c.json({ error: 'Email log not found' }, 404);
|
||||
@@ -362,22 +357,22 @@ emailsRouter.get('/stats', requireAuth(['admin', 'organizer']), async (c) => {
|
||||
? (db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(baseCondition)
|
||||
: (db as any).select({ count: sql<number>`count(*)` }).from(emailLogs);
|
||||
|
||||
const total = (await totalQuery.get())?.count || 0;
|
||||
const total = (await dbGet<any>(totalQuery))?.count || 0;
|
||||
|
||||
const sentCondition = baseCondition
|
||||
? and(baseCondition, eq((emailLogs as any).status, 'sent'))
|
||||
: eq((emailLogs as any).status, 'sent');
|
||||
const sent = (await (db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(sentCondition).get())?.count || 0;
|
||||
const sent = (await dbGet<any>((db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(sentCondition)))?.count || 0;
|
||||
|
||||
const failedCondition = baseCondition
|
||||
? and(baseCondition, eq((emailLogs as any).status, 'failed'))
|
||||
: eq((emailLogs as any).status, 'failed');
|
||||
const failed = (await (db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(failedCondition).get())?.count || 0;
|
||||
const failed = (await dbGet<any>((db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(failedCondition)))?.count || 0;
|
||||
|
||||
const pendingCondition = baseCondition
|
||||
? and(baseCondition, eq((emailLogs as any).status, 'pending'))
|
||||
: eq((emailLogs as any).status, 'pending');
|
||||
const pending = (await (db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(pendingCondition).get())?.count || 0;
|
||||
const pending = (await dbGet<any>((db as any).select({ count: sql<number>`count(*)` }).from(emailLogs).where(pendingCondition)))?.count || 0;
|
||||
|
||||
return c.json({
|
||||
stats: {
|
||||
|
||||
Reference in New Issue
Block a user