mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-08-30 12:09:54 +00:00
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
This commit is contained in:
+122
-9
@@ -200,21 +200,134 @@ export class DatabaseStorage implements IStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createDomain(domain: InsertDomain): Promise<Domain> {
|
async createDomain(domain: InsertDomain): Promise<Domain> {
|
||||||
const [newDomain] = await db.insert(domains).values(domain).returning();
|
try {
|
||||||
return newDomain;
|
// 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<InsertDomain>): Promise<Domain | undefined> {
|
async updateDomain(id: string, domainData: Partial<InsertDomain>): Promise<Domain | undefined> {
|
||||||
const [updatedDomain] = await db.update(domains)
|
try {
|
||||||
.set({ ...domainData, lastUpdated: new Date() })
|
// Check if the domain exists first
|
||||||
.where(eq(domains.id, id))
|
const existingDomain = await this.getDomain(id);
|
||||||
.returning();
|
if (!existingDomain) {
|
||||||
return updatedDomain;
|
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<boolean> {
|
async deleteDomain(id: string): Promise<boolean> {
|
||||||
const result = await db.delete(domains).where(eq(domains.id, id)).returning();
|
try {
|
||||||
return result.length > 0;
|
// 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
|
// DNS Record management
|
||||||
|
|||||||
+4
-2
@@ -205,7 +205,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
|
|
||||||
app.put("/api/domains/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
app.put("/api/domains/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
try {
|
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 validatedData = insertDomainSchema.partial().parse(req.body);
|
||||||
|
|
||||||
const updatedDomain = await storage.updateDomain(id, validatedData);
|
const updatedDomain = await storage.updateDomain(id, validatedData);
|
||||||
@@ -227,7 +228,8 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
|
|
||||||
app.delete("/api/domains/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
app.delete("/api/domains/:id", requireRole(["admin", "manager"]), async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const id = parseInt(req.params.id);
|
// Use id as string without parsing
|
||||||
|
const id = req.params.id;
|
||||||
const deleted = await storage.deleteDomain(id);
|
const deleted = await storage.deleteDomain(id);
|
||||||
|
|
||||||
if (!deleted) {
|
if (!deleted) {
|
||||||
|
|||||||
Reference in New Issue
Block a user