From f12e76d2063a3919fb722b09eb8206fda5f87ac7 Mon Sep 17 00:00:00 2001 From: alphaeusmote <41258468-alphaeusmote@users.noreply.replit.com> Date: Thu, 10 Apr 2025 03:47:54 +0000 Subject: [PATCH] Improve domain management by using raw SQL queries for database interactions. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/022cff8c-1cb5-4dc8-8647-65fb658bdd0c.jpg --- server/database-storage.ts | 131 ++++++++++++++++++++++++++++++++++--- server/routes.ts | 6 +- 2 files changed, 126 insertions(+), 11 deletions(-) diff --git a/server/database-storage.ts b/server/database-storage.ts index 65840ea..758d8cf 100644 --- a/server/database-storage.ts +++ b/server/database-storage.ts @@ -200,21 +200,134 @@ export class DatabaseStorage implements IStorage { } async createDomain(domain: InsertDomain): Promise { - const [newDomain] = await db.insert(domains).values(domain).returning(); - return newDomain; + try { + // Use raw SQL to avoid schema issues + const now = new Date().toISOString(); + const query = sql` + INSERT INTO domains ( + id, + name, + organization_id, + is_active, + provider_id, + created_at + ) VALUES ( + gen_random_uuid(), + ${domain.name}, + ${domain.organizationId}, + ${domain.isActive}, + ${domain.providerId || null}, + ${now} + ) + RETURNING + id, + name, + organization_id as "organizationId", + is_active as "isActive", + provider_id as "providerId", + created_at as "createdAt" + `; + + const result = await db.execute(query); + + if (!result.rows || result.rows.length === 0) { + throw new Error("Failed to create domain"); + } + + const row = result.rows[0]; + + // Map to Domain type + return { + id: row.id as string, + name: row.name as string, + organizationId: row.organizationId as string, + isActive: Boolean(row.isActive), + providerId: row.providerId as string, + createdAt: row.createdAt ? new Date(row.createdAt as string) : new Date(), + lastUpdated: new Date() // Use creation date as the last updated date + }; + } catch (error) { + console.error("Error creating domain:", error); + throw error; + } } async updateDomain(id: string, domainData: Partial): Promise { - const [updatedDomain] = await db.update(domains) - .set({ ...domainData, lastUpdated: new Date() }) - .where(eq(domains.id, id)) - .returning(); - return updatedDomain; + try { + // Check if the domain exists first + const existingDomain = await this.getDomain(id); + if (!existingDomain) { + return undefined; + } + + // Use raw SQL to avoid schema issues + const updateFields = Object.entries(domainData) + .map(([key, value]) => `${key === 'organizationId' ? 'organization_id' : + key === 'isActive' ? 'is_active' : key} = ${ + typeof value === 'string' ? `'${value}'` : + typeof value === 'boolean' ? value : + value === null ? 'NULL' : `'${value}'` + }`) + .join(', '); + + // Add lastUpdated field (using database naming convention) + const now = new Date().toISOString(); + const query = sql` + UPDATE domains + SET ${sql.raw(updateFields)}, last_updated = ${now} + WHERE id = ${id} + RETURNING + id, + name, + organization_id as "organizationId", + is_active as "isActive", + created_at as "createdAt" + `; + + const result = await db.execute(query); + + if (!result.rows || result.rows.length === 0) { + return undefined; + } + + const row = result.rows[0]; + + // Map to Domain type with expected fields + return { + id: row.id as string, + name: row.name as string, + organizationId: row.organizationId as string, + isActive: Boolean(row.isActive), + createdAt: row.createdAt ? new Date(row.createdAt as string) : new Date(), + providerId: existingDomain.providerId || '', // Keep existing value + lastUpdated: new Date() // Use current date for lastUpdated + }; + } catch (error) { + console.error("Error updating domain:", error); + return undefined; + } } async deleteDomain(id: string): Promise { - const result = await db.delete(domains).where(eq(domains.id, id)).returning(); - return result.length > 0; + try { + // Check first if the domain exists + const domain = await this.getDomain(id); + if (!domain) { + return false; + } + + // Use raw SQL to avoid schema issues + const result = await db.execute(sql` + DELETE FROM domains + WHERE id = ${id} + RETURNING id + `); + + return result.rows?.length > 0; + } catch (error) { + console.error("Error deleting domain:", error); + return false; + } } // DNS Record management diff --git a/server/routes.ts b/server/routes.ts index 51b8a36..2f3a00c 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -205,7 +205,8 @@ export async function registerRoutes(app: Express): Promise { app.put("/api/domains/:id", requireRole(["admin", "manager"]), async (req, res) => { try { - const id = parseInt(req.params.id); + // Use id as string without parsing to int + const id = req.params.id; const validatedData = insertDomainSchema.partial().parse(req.body); const updatedDomain = await storage.updateDomain(id, validatedData); @@ -227,7 +228,8 @@ export async function registerRoutes(app: Express): Promise { app.delete("/api/domains/:id", requireRole(["admin", "manager"]), async (req, res) => { try { - const id = parseInt(req.params.id); + // Use id as string without parsing + const id = req.params.id; const deleted = await storage.deleteDomain(id); if (!deleted) {