Refactor monolithic modules and harden booking, email, and auth infrastructure.

Split oversized frontend API client, email service, and admin/booking pages into focused modules while preserving import surfaces, and add Redis-backed queues, stale booking cleanup, stronger auth, and scale deployment configs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Michilis
2026-06-25 07:12:59 +00:00
co-authored by Cursor
parent f0e2de2834
commit 613bd7be1d
75 changed files with 7702 additions and 5580 deletions
+8 -23
View File
@@ -3,13 +3,10 @@ import { db, dbGet, dbAll, media } from '../db/index.js';
import { eq, and } from 'drizzle-orm';
import { requireAuth } from '../lib/auth.js';
import { generateId, getNow } from '../lib/utils.js';
import { writeFile, mkdir, unlink } from 'fs/promises';
import { existsSync } from 'fs';
import { join } from 'path';
import { getStorage, keyFromUrl } from '../lib/storage.js';
const mediaRouter = new Hono();
const UPLOAD_DIR = './uploads';
const MAX_FILE_SIZE =
(Number(process.env.MEDIA_MAX_UPLOAD_MB || '10') || 10) * 1024 * 1024; // default 10MB
@@ -51,13 +48,6 @@ function detectImageType(buf: Buffer): { mime: string; ext: string } | null {
return null;
}
// Ensure upload directory exists
async function ensureUploadDir() {
if (!existsSync(UPLOAD_DIR)) {
await mkdir(UPLOAD_DIR, { recursive: true });
}
}
// Upload image
mediaRouter.post('/upload', requireAuth(['admin', 'organizer']), async (c) => {
try {
@@ -83,15 +73,13 @@ mediaRouter.post('/upload', requireAuth(['admin', 'organizer']), async (c) => {
return c.json({ error: 'Invalid file. Allowed: JPEG, PNG, GIF, WebP, AVIF' }, 400);
}
await ensureUploadDir();
// Generate unique filename using the *detected* extension (ignore client filename)
const id = generateId();
const filename = `${id}${detected.ext}`;
const filepath = join(UPLOAD_DIR, filename);
// Write file
await writeFile(filepath, buffer);
// Persist via the storage backend (local disk or S3-compatible object store).
const storage = getStorage();
await storage.put(filename, buffer, detected.mime);
// Get related info from form data
const relatedId = body['relatedId'] as string | undefined;
@@ -101,7 +89,7 @@ mediaRouter.post('/upload', requireAuth(['admin', 'organizer']), async (c) => {
const now = getNow();
const mediaRecord = {
id,
fileUrl: `/uploads/${filename}`,
fileUrl: storage.publicUrl(filename),
type: 'image' as const,
relatedId: relatedId || null,
relatedType: relatedType || null,
@@ -147,12 +135,9 @@ mediaRouter.delete('/:id', requireAuth(['admin', 'organizer']), async (c) => {
return c.json({ error: 'Media not found' }, 404);
}
// Delete file from disk
// Delete the underlying object from the storage backend.
try {
const filepath = join('.', mediaRecord.fileUrl);
if (existsSync(filepath)) {
await unlink(filepath);
}
await getStorage().delete(keyFromUrl(mediaRecord.fileUrl));
} catch (error) {
console.error('Failed to delete file:', error);
}